#!/usr/bin/perl -w
# $Id: Rijndael_PP.pm,v 1.20 2001/08/16 08:55:16 lackas Exp $
package Crypt::Rijndael_PP;

require 5.004;
use strict;
use integer;
use Carp;

use vars qw'$VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA';
require Exporter;

@ISA = 'Exporter';
$VERSION = 0.04;
@EXPORT_OK = qw(
	blockDecrypt blockEncrypt blockEncryptRound blockDecryptRound
	cipherUpdateRounds cipherInit makeKey
	MODE_ECB MODE_CBC MODE_CFB1
	DIR_ENCRYPT DIR_DECRYPT
);
@EXPORT = qw(rijndael_encrypt rijndael_decrypt);
%EXPORT_TAGS = (
	all => [@EXPORT_OK,@EXPORT],
	modes => [qw(MODE_ECB MODE_CBC MODE_CFB1)],
	directions => [qw(DIR_ENCRYPT DIR_DECRYPT)],
	CAPI => [qw(cipherInit makeKey blockDecrypt blockEncrypt)]
);


# boxes-ref.dat
use constant Logtable => [
  0,   0,  25,   1,  50,   2,  26, 198,  75, 199,  27, 104,  51, 238, 223,   3, 
100,   4, 224,  14,  52, 141, 129, 239,  76, 113,   8, 200, 248, 105,  28, 193, 
125, 194,  29, 181, 249, 185,  39, 106,  77, 228, 166, 114, 154, 201,   9, 120, 
101,  47, 138,   5,  33,  15, 225,  36,  18, 240, 130,  69,  53, 147, 218, 142, 
150, 143, 219, 189,  54, 208, 206, 148,  19,  92, 210, 241,  64,  70, 131,  56, 
102, 221, 253,  48, 191,   6, 139,  98, 179,  37, 226, 152,  34, 136, 145,  16, 
126, 110,  72, 195, 163, 182,  30,  66,  58, 107,  40,  84, 250, 133,  61, 186, 
 43, 121,  10,  21, 155, 159,  94, 202,  78, 212, 172, 229, 243, 115, 167,  87, 
175,  88, 168,  80, 244, 234, 214, 116,  79, 174, 233, 213, 231, 230, 173, 232, 
 44, 215, 117, 122, 235,  22,  11, 245,  89, 203,  95, 176, 156, 169,  81, 160, 
127,  12, 246, 111,  23, 196,  73, 236, 216,  67,  31,  45, 164, 118, 123, 183, 
204, 187,  62,  90, 251,  96, 177, 134,  59,  82, 161, 108, 170,  85,  41, 157, 
151, 178, 135, 144,  97, 190, 220, 252, 188, 149, 207, 205,  55,  63,  91, 209, 
 83,  57, 132,  60,  65, 162, 109,  71,  20,  42, 158,  93,  86, 242, 211, 171, 
 68,  17, 146, 217,  35,  32,  46, 137, 180, 124, 184,  38, 119, 153, 227, 165, 
103,  74, 237, 222, 197,  49, 254,  24,  13,  99, 140, 128, 192, 247, 112,   7 
];

use constant Algotable => [
  1,   3,   5,  15,  17,  51,  85, 255,  26,  46, 114, 150, 161, 248,  19,  53, 
 95, 225,  56,  72, 216, 115, 149, 164, 247,   2,   6,  10,  30,  34, 102, 170, 
229,  52,  92, 228,  55,  89, 235,  38, 106, 190, 217, 112, 144, 171, 230,  49, 
 83, 245,   4,  12,  20,  60,  68, 204,  79, 209, 104, 184, 211, 110, 178, 205, 
 76, 212, 103, 169, 224,  59,  77, 215,  98, 166, 241,   8,  24,  40, 120, 136, 
131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206,  73, 219, 118, 154, 
181, 196,  87, 249,  16,  48,  80, 240,  11,  29,  39, 105, 187, 214,  97, 163, 
254,  25,  43, 125, 135, 146, 173, 236,  47, 113, 147, 174, 233,  32,  96, 160, 
251,  22,  58,  78, 210, 109, 183, 194,  93, 231,  50,  86, 250,  21,  63,  65, 
195,  94, 226,  61,  71, 201,  64, 192,  91, 237,  44, 116, 156, 191, 218, 117, 
159, 186, 213, 100, 172, 239,  42, 126, 130, 157, 188, 223, 122, 142, 137, 128, 
155, 182, 193,  88, 232,  35, 101, 175, 234,  37, 111, 177, 200,  67, 197,  84, 
252,  31,  33,  99, 165, 244,   7,   9,  27,  45, 119, 153, 176, 203,  70, 202, 
 69, 207,  74, 222, 121, 139, 134, 145, 168, 227,  62,  66, 198,  81, 243,  14, 
 18,  54,  90, 238,  41, 123, 141, 140, 143, 138, 133, 148, 167, 242,  13,  23, 
 57,  75, 221, 124, 132, 151, 162, 253,  28,  36, 108, 180, 199,  82, 246,   1 
];

my @S = (
 99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
  4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
  9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
 83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
 81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
 96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22 
);

my @Si = (
 82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 251, 
124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 233, 203, 
 84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78, 
  8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, 
114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101, 182, 146, 
108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, 
144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6, 
208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107, 
 58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 
150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,  28, 117, 223, 110, 
 71, 241,  26, 113,  29,  41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, 
252,  86,  62,  75, 198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244, 
 31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95, 
 96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, 
160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, 
 23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12, 125
);

my @iG = (
	[ 0x0e, 0x09, 0x0d, 0x0b ],
	[ 0x0b, 0x0e, 0x09, 0x0d ], 
	[ 0x0d, 0x0b, 0x0e, 0x09 ], 
	[ 0x09, 0x0d, 0x0b, 0x0e ]
);

my @rcon = ( 
	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 
	0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 
	0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 
	0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
);

my @T1 = (
	[0xc6,0x63,0x63,0xa5], [0xf8,0x7c,0x7c,0x84], [0xee,0x77,0x77,0x99], [0xf6,0x7b,0x7b,0x8d], 
	[0xff,0xf2,0xf2,0x0d], [0xd6,0x6b,0x6b,0xbd], [0xde,0x6f,0x6f,0xb1], [0x91,0xc5,0xc5,0x54], 
	[0x60,0x30,0x30,0x50], [0x02,0x01,0x01,0x03], [0xce,0x67,0x67,0xa9], [0x56,0x2b,0x2b,0x7d], 
	[0xe7,0xfe,0xfe,0x19], [0xb5,0xd7,0xd7,0x62], [0x4d,0xab,0xab,0xe6], [0xec,0x76,0x76,0x9a], 
	[0x8f,0xca,0xca,0x45], [0x1f,0x82,0x82,0x9d], [0x89,0xc9,0xc9,0x40], [0xfa,0x7d,0x7d,0x87], 
	[0xef,0xfa,0xfa,0x15], [0xb2,0x59,0x59,0xeb], [0x8e,0x47,0x47,0xc9], [0xfb,0xf0,0xf0,0x0b], 
	[0x41,0xad,0xad,0xec], [0xb3,0xd4,0xd4,0x67], [0x5f,0xa2,0xa2,0xfd], [0x45,0xaf,0xaf,0xea], 
	[0x23,0x9c,0x9c,0xbf], [0x53,0xa4,0xa4,0xf7], [0xe4,0x72,0x72,0x96], [0x9b,0xc0,0xc0,0x5b], 
	[0x75,0xb7,0xb7,0xc2], [0xe1,0xfd,0xfd,0x1c], [0x3d,0x93,0x93,0xae], [0x4c,0x26,0x26,0x6a], 
	[0x6c,0x36,0x36,0x5a], [0x7e,0x3f,0x3f,0x41], [0xf5,0xf7,0xf7,0x02], [0x83,0xcc,0xcc,0x4f], 
	[0x68,0x34,0x34,0x5c], [0x51,0xa5,0xa5,0xf4], [0xd1,0xe5,0xe5,0x34], [0xf9,0xf1,0xf1,0x08], 
	[0xe2,0x71,0x71,0x93], [0xab,0xd8,0xd8,0x73], [0x62,0x31,0x31,0x53], [0x2a,0x15,0x15,0x3f], 
	[0x08,0x04,0x04,0x0c], [0x95,0xc7,0xc7,0x52], [0x46,0x23,0x23,0x65], [0x9d,0xc3,0xc3,0x5e], 
	[0x30,0x18,0x18,0x28], [0x37,0x96,0x96,0xa1], [0x0a,0x05,0x05,0x0f], [0x2f,0x9a,0x9a,0xb5], 
	[0x0e,0x07,0x07,0x09], [0x24,0x12,0x12,0x36], [0x1b,0x80,0x80,0x9b], [0xdf,0xe2,0xe2,0x3d], 
	[0xcd,0xeb,0xeb,0x26], [0x4e,0x27,0x27,0x69], [0x7f,0xb2,0xb2,0xcd], [0xea,0x75,0x75,0x9f], 
	[0x12,0x09,0x09,0x1b], [0x1d,0x83,0x83,0x9e], [0x58,0x2c,0x2c,0x74], [0x34,0x1a,0x1a,0x2e], 
	[0x36,0x1b,0x1b,0x2d], [0xdc,0x6e,0x6e,0xb2], [0xb4,0x5a,0x5a,0xee], [0x5b,0xa0,0xa0,0xfb], 
	[0xa4,0x52,0x52,0xf6], [0x76,0x3b,0x3b,0x4d], [0xb7,0xd6,0xd6,0x61], [0x7d,0xb3,0xb3,0xce], 
	[0x52,0x29,0x29,0x7b], [0xdd,0xe3,0xe3,0x3e], [0x5e,0x2f,0x2f,0x71], [0x13,0x84,0x84,0x97], 
	[0xa6,0x53,0x53,0xf5], [0xb9,0xd1,0xd1,0x68], [0x00,0x00,0x00,0x00], [0xc1,0xed,0xed,0x2c], 
	[0x40,0x20,0x20,0x60], [0xe3,0xfc,0xfc,0x1f], [0x79,0xb1,0xb1,0xc8], [0xb6,0x5b,0x5b,0xed], 
	[0xd4,0x6a,0x6a,0xbe], [0x8d,0xcb,0xcb,0x46], [0x67,0xbe,0xbe,0xd9], [0x72,0x39,0x39,0x4b], 
	[0x94,0x4a,0x4a,0xde], [0x98,0x4c,0x4c,0xd4], [0xb0,0x58,0x58,0xe8], [0x85,0xcf,0xcf,0x4a], 
	[0xbb,0xd0,0xd0,0x6b], [0xc5,0xef,0xef,0x2a], [0x4f,0xaa,0xaa,0xe5], [0xed,0xfb,0xfb,0x16], 
	[0x86,0x43,0x43,0xc5], [0x9a,0x4d,0x4d,0xd7], [0x66,0x33,0x33,0x55], [0x11,0x85,0x85,0x94], 
	[0x8a,0x45,0x45,0xcf], [0xe9,0xf9,0xf9,0x10], [0x04,0x02,0x02,0x06], [0xfe,0x7f,0x7f,0x81], 
	[0xa0,0x50,0x50,0xf0], [0x78,0x3c,0x3c,0x44], [0x25,0x9f,0x9f,0xba], [0x4b,0xa8,0xa8,0xe3], 
	[0xa2,0x51,0x51,0xf3], [0x5d,0xa3,0xa3,0xfe], [0x80,0x40,0x40,0xc0], [0x05,0x8f,0x8f,0x8a], 
	[0x3f,0x92,0x92,0xad], [0x21,0x9d,0x9d,0xbc], [0x70,0x38,0x38,0x48], [0xf1,0xf5,0xf5,0x04], 
	[0x63,0xbc,0xbc,0xdf], [0x77,0xb6,0xb6,0xc1], [0xaf,0xda,0xda,0x75], [0x42,0x21,0x21,0x63], 
	[0x20,0x10,0x10,0x30], [0xe5,0xff,0xff,0x1a], [0xfd,0xf3,0xf3,0x0e], [0xbf,0xd2,0xd2,0x6d], 
	[0x81,0xcd,0xcd,0x4c], [0x18,0x0c,0x0c,0x14], [0x26,0x13,0x13,0x35], [0xc3,0xec,0xec,0x2f], 
	[0xbe,0x5f,0x5f,0xe1], [0x35,0x97,0x97,0xa2], [0x88,0x44,0x44,0xcc], [0x2e,0x17,0x17,0x39], 
	[0x93,0xc4,0xc4,0x57], [0x55,0xa7,0xa7,0xf2], [0xfc,0x7e,0x7e,0x82], [0x7a,0x3d,0x3d,0x47], 
	[0xc8,0x64,0x64,0xac], [0xba,0x5d,0x5d,0xe7], [0x32,0x19,0x19,0x2b], [0xe6,0x73,0x73,0x95], 
	[0xc0,0x60,0x60,0xa0], [0x19,0x81,0x81,0x98], [0x9e,0x4f,0x4f,0xd1], [0xa3,0xdc,0xdc,0x7f], 
	[0x44,0x22,0x22,0x66], [0x54,0x2a,0x2a,0x7e], [0x3b,0x90,0x90,0xab], [0x0b,0x88,0x88,0x83], 
	[0x8c,0x46,0x46,0xca], [0xc7,0xee,0xee,0x29], [0x6b,0xb8,0xb8,0xd3], [0x28,0x14,0x14,0x3c], 
	[0xa7,0xde,0xde,0x79], [0xbc,0x5e,0x5e,0xe2], [0x16,0x0b,0x0b,0x1d], [0xad,0xdb,0xdb,0x76], 
	[0xdb,0xe0,0xe0,0x3b], [0x64,0x32,0x32,0x56], [0x74,0x3a,0x3a,0x4e], [0x14,0x0a,0x0a,0x1e], 
	[0x92,0x49,0x49,0xdb], [0x0c,0x06,0x06,0x0a], [0x48,0x24,0x24,0x6c], [0xb8,0x5c,0x5c,0xe4], 
	[0x9f,0xc2,0xc2,0x5d], [0xbd,0xd3,0xd3,0x6e], [0x43,0xac,0xac,0xef], [0xc4,0x62,0x62,0xa6], 
	[0x39,0x91,0x91,0xa8], [0x31,0x95,0x95,0xa4], [0xd3,0xe4,0xe4,0x37], [0xf2,0x79,0x79,0x8b], 
	[0xd5,0xe7,0xe7,0x32], [0x8b,0xc8,0xc8,0x43], [0x6e,0x37,0x37,0x59], [0xda,0x6d,0x6d,0xb7], 
	[0x01,0x8d,0x8d,0x8c], [0xb1,0xd5,0xd5,0x64], [0x9c,0x4e,0x4e,0xd2], [0x49,0xa9,0xa9,0xe0], 
	[0xd8,0x6c,0x6c,0xb4], [0xac,0x56,0x56,0xfa], [0xf3,0xf4,0xf4,0x07], [0xcf,0xea,0xea,0x25], 
	[0xca,0x65,0x65,0xaf], [0xf4,0x7a,0x7a,0x8e], [0x47,0xae,0xae,0xe9], [0x10,0x08,0x08,0x18], 
	[0x6f,0xba,0xba,0xd5], [0xf0,0x78,0x78,0x88], [0x4a,0x25,0x25,0x6f], [0x5c,0x2e,0x2e,0x72], 
	[0x38,0x1c,0x1c,0x24], [0x57,0xa6,0xa6,0xf1], [0x73,0xb4,0xb4,0xc7], [0x97,0xc6,0xc6,0x51], 
	[0xcb,0xe8,0xe8,0x23], [0xa1,0xdd,0xdd,0x7c], [0xe8,0x74,0x74,0x9c], [0x3e,0x1f,0x1f,0x21], 
	[0x96,0x4b,0x4b,0xdd], [0x61,0xbd,0xbd,0xdc], [0x0d,0x8b,0x8b,0x86], [0x0f,0x8a,0x8a,0x85], 
	[0xe0,0x70,0x70,0x90], [0x7c,0x3e,0x3e,0x42], [0x71,0xb5,0xb5,0xc4], [0xcc,0x66,0x66,0xaa], 
	[0x90,0x48,0x48,0xd8], [0x06,0x03,0x03,0x05], [0xf7,0xf6,0xf6,0x01], [0x1c,0x0e,0x0e,0x12], 
	[0xc2,0x61,0x61,0xa3], [0x6a,0x35,0x35,0x5f], [0xae,0x57,0x57,0xf9], [0x69,0xb9,0xb9,0xd0], 
	[0x17,0x86,0x86,0x91], [0x99,0xc1,0xc1,0x58], [0x3a,0x1d,0x1d,0x27], [0x27,0x9e,0x9e,0xb9], 
	[0xd9,0xe1,0xe1,0x38], [0xeb,0xf8,0xf8,0x13], [0x2b,0x98,0x98,0xb3], [0x22,0x11,0x11,0x33], 
	[0xd2,0x69,0x69,0xbb], [0xa9,0xd9,0xd9,0x70], [0x07,0x8e,0x8e,0x89], [0x33,0x94,0x94,0xa7], 
	[0x2d,0x9b,0x9b,0xb6], [0x3c,0x1e,0x1e,0x22], [0x15,0x87,0x87,0x92], [0xc9,0xe9,0xe9,0x20], 
	[0x87,0xce,0xce,0x49], [0xaa,0x55,0x55,0xff], [0x50,0x28,0x28,0x78], [0xa5,0xdf,0xdf,0x7a], 
	[0x03,0x8c,0x8c,0x8f], [0x59,0xa1,0xa1,0xf8], [0x09,0x89,0x89,0x80], [0x1a,0x0d,0x0d,0x17], 
	[0x65,0xbf,0xbf,0xda], [0xd7,0xe6,0xe6,0x31], [0x84,0x42,0x42,0xc6], [0xd0,0x68,0x68,0xb8], 
	[0x82,0x41,0x41,0xc3], [0x29,0x99,0x99,0xb0], [0x5a,0x2d,0x2d,0x77], [0x1e,0x0f,0x0f,0x11], 
	[0x7b,0xb0,0xb0,0xcb], [0xa8,0x54,0x54,0xfc], [0x6d,0xbb,0xbb,0xd6], [0x2c,0x16,0x16,0x3a]
);

my @T2 = (
	[0xa5,0xc6,0x63,0x63], [0x84,0xf8,0x7c,0x7c], [0x99,0xee,0x77,0x77], [0x8d,0xf6,0x7b,0x7b], 
	[0x0d,0xff,0xf2,0xf2], [0xbd,0xd6,0x6b,0x6b], [0xb1,0xde,0x6f,0x6f], [0x54,0x91,0xc5,0xc5], 
	[0x50,0x60,0x30,0x30], [0x03,0x02,0x01,0x01], [0xa9,0xce,0x67,0x67], [0x7d,0x56,0x2b,0x2b], 
	[0x19,0xe7,0xfe,0xfe], [0x62,0xb5,0xd7,0xd7], [0xe6,0x4d,0xab,0xab], [0x9a,0xec,0x76,0x76], 
	[0x45,0x8f,0xca,0xca], [0x9d,0x1f,0x82,0x82], [0x40,0x89,0xc9,0xc9], [0x87,0xfa,0x7d,0x7d], 
	[0x15,0xef,0xfa,0xfa], [0xeb,0xb2,0x59,0x59], [0xc9,0x8e,0x47,0x47], [0x0b,0xfb,0xf0,0xf0], 
	[0xec,0x41,0xad,0xad], [0x67,0xb3,0xd4,0xd4], [0xfd,0x5f,0xa2,0xa2], [0xea,0x45,0xaf,0xaf], 
	[0xbf,0x23,0x9c,0x9c], [0xf7,0x53,0xa4,0xa4], [0x96,0xe4,0x72,0x72], [0x5b,0x9b,0xc0,0xc0], 
	[0xc2,0x75,0xb7,0xb7], [0x1c,0xe1,0xfd,0xfd], [0xae,0x3d,0x93,0x93], [0x6a,0x4c,0x26,0x26], 
	[0x5a,0x6c,0x36,0x36], [0x41,0x7e,0x3f,0x3f], [0x02,0xf5,0xf7,0xf7], [0x4f,0x83,0xcc,0xcc], 
	[0x5c,0x68,0x34,0x34], [0xf4,0x51,0xa5,0xa5], [0x34,0xd1,0xe5,0xe5], [0x08,0xf9,0xf1,0xf1], 
	[0x93,0xe2,0x71,0x71], [0x73,0xab,0xd8,0xd8], [0x53,0x62,0x31,0x31], [0x3f,0x2a,0x15,0x15], 
	[0x0c,0x08,0x04,0x04], [0x52,0x95,0xc7,0xc7], [0x65,0x46,0x23,0x23], [0x5e,0x9d,0xc3,0xc3], 
	[0x28,0x30,0x18,0x18], [0xa1,0x37,0x96,0x96], [0x0f,0x0a,0x05,0x05], [0xb5,0x2f,0x9a,0x9a], 
	[0x09,0x0e,0x07,0x07], [0x36,0x24,0x12,0x12], [0x9b,0x1b,0x80,0x80], [0x3d,0xdf,0xe2,0xe2], 
	[0x26,0xcd,0xeb,0xeb], [0x69,0x4e,0x27,0x27], [0xcd,0x7f,0xb2,0xb2], [0x9f,0xea,0x75,0x75], 
	[0x1b,0x12,0x09,0x09], [0x9e,0x1d,0x83,0x83], [0x74,0x58,0x2c,0x2c], [0x2e,0x34,0x1a,0x1a], 
	[0x2d,0x36,0x1b,0x1b], [0xb2,0xdc,0x6e,0x6e], [0xee,0xb4,0x5a,0x5a], [0xfb,0x5b,0xa0,0xa0], 
	[0xf6,0xa4,0x52,0x52], [0x4d,0x76,0x3b,0x3b], [0x61,0xb7,0xd6,0xd6], [0xce,0x7d,0xb3,0xb3], 
	[0x7b,0x52,0x29,0x29], [0x3e,0xdd,0xe3,0xe3], [0x71,0x5e,0x2f,0x2f], [0x97,0x13,0x84,0x84], 
	[0xf5,0xa6,0x53,0x53], [0x68,0xb9,0xd1,0xd1], [0x00,0x00,0x00,0x00], [0x2c,0xc1,0xed,0xed], 
	[0x60,0x40,0x20,0x20], [0x1f,0xe3,0xfc,0xfc], [0xc8,0x79,0xb1,0xb1], [0xed,0xb6,0x5b,0x5b], 
	[0xbe,0xd4,0x6a,0x6a], [0x46,0x8d,0xcb,0xcb], [0xd9,0x67,0xbe,0xbe], [0x4b,0x72,0x39,0x39], 
	[0xde,0x94,0x4a,0x4a], [0xd4,0x98,0x4c,0x4c], [0xe8,0xb0,0x58,0x58], [0x4a,0x85,0xcf,0xcf], 
	[0x6b,0xbb,0xd0,0xd0], [0x2a,0xc5,0xef,0xef], [0xe5,0x4f,0xaa,0xaa], [0x16,0xed,0xfb,0xfb], 
	[0xc5,0x86,0x43,0x43], [0xd7,0x9a,0x4d,0x4d], [0x55,0x66,0x33,0x33], [0x94,0x11,0x85,0x85], 
	[0xcf,0x8a,0x45,0x45], [0x10,0xe9,0xf9,0xf9], [0x06,0x04,0x02,0x02], [0x81,0xfe,0x7f,0x7f], 
	[0xf0,0xa0,0x50,0x50], [0x44,0x78,0x3c,0x3c], [0xba,0x25,0x9f,0x9f], [0xe3,0x4b,0xa8,0xa8], 
	[0xf3,0xa2,0x51,0x51], [0xfe,0x5d,0xa3,0xa3], [0xc0,0x80,0x40,0x40], [0x8a,0x05,0x8f,0x8f], 
	[0xad,0x3f,0x92,0x92], [0xbc,0x21,0x9d,0x9d], [0x48,0x70,0x38,0x38], [0x04,0xf1,0xf5,0xf5], 
	[0xdf,0x63,0xbc,0xbc], [0xc1,0x77,0xb6,0xb6], [0x75,0xaf,0xda,0xda], [0x63,0x42,0x21,0x21], 
	[0x30,0x20,0x10,0x10], [0x1a,0xe5,0xff,0xff], [0x0e,0xfd,0xf3,0xf3], [0x6d,0xbf,0xd2,0xd2], 
	[0x4c,0x81,0xcd,0xcd], [0x14,0x18,0x0c,0x0c], [0x35,0x26,0x13,0x13], [0x2f,0xc3,0xec,0xec], 
	[0xe1,0xbe,0x5f,0x5f], [0xa2,0x35,0x97,0x97], [0xcc,0x88,0x44,0x44], [0x39,0x2e,0x17,0x17], 
	[0x57,0x93,0xc4,0xc4], [0xf2,0x55,0xa7,0xa7], [0x82,0xfc,0x7e,0x7e], [0x47,0x7a,0x3d,0x3d], 
	[0xac,0xc8,0x64,0x64], [0xe7,0xba,0x5d,0x5d], [0x2b,0x32,0x19,0x19], [0x95,0xe6,0x73,0x73], 
	[0xa0,0xc0,0x60,0x60], [0x98,0x19,0x81,0x81], [0xd1,0x9e,0x4f,0x4f], [0x7f,0xa3,0xdc,0xdc], 
	[0x66,0x44,0x22,0x22], [0x7e,0x54,0x2a,0x2a], [0xab,0x3b,0x90,0x90], [0x83,0x0b,0x88,0x88], 
	[0xca,0x8c,0x46,0x46], [0x29,0xc7,0xee,0xee], [0xd3,0x6b,0xb8,0xb8], [0x3c,0x28,0x14,0x14], 
	[0x79,0xa7,0xde,0xde], [0xe2,0xbc,0x5e,0x5e], [0x1d,0x16,0x0b,0x0b], [0x76,0xad,0xdb,0xdb], 
	[0x3b,0xdb,0xe0,0xe0], [0x56,0x64,0x32,0x32], [0x4e,0x74,0x3a,0x3a], [0x1e,0x14,0x0a,0x0a], 
	[0xdb,0x92,0x49,0x49], [0x0a,0x0c,0x06,0x06], [0x6c,0x48,0x24,0x24], [0xe4,0xb8,0x5c,0x5c], 
	[0x5d,0x9f,0xc2,0xc2], [0x6e,0xbd,0xd3,0xd3], [0xef,0x43,0xac,0xac], [0xa6,0xc4,0x62,0x62], 
	[0xa8,0x39,0x91,0x91], [0xa4,0x31,0x95,0x95], [0x37,0xd3,0xe4,0xe4], [0x8b,0xf2,0x79,0x79], 
	[0x32,0xd5,0xe7,0xe7], [0x43,0x8b,0xc8,0xc8], [0x59,0x6e,0x37,0x37], [0xb7,0xda,0x6d,0x6d], 
	[0x8c,0x01,0x8d,0x8d], [0x64,0xb1,0xd5,0xd5], [0xd2,0x9c,0x4e,0x4e], [0xe0,0x49,0xa9,0xa9], 
	[0xb4,0xd8,0x6c,0x6c], [0xfa,0xac,0x56,0x56], [0x07,0xf3,0xf4,0xf4], [0x25,0xcf,0xea,0xea], 
	[0xaf,0xca,0x65,0x65], [0x8e,0xf4,0x7a,0x7a], [0xe9,0x47,0xae,0xae], [0x18,0x10,0x08,0x08], 
	[0xd5,0x6f,0xba,0xba], [0x88,0xf0,0x78,0x78], [0x6f,0x4a,0x25,0x25], [0x72,0x5c,0x2e,0x2e], 
	[0x24,0x38,0x1c,0x1c], [0xf1,0x57,0xa6,0xa6], [0xc7,0x73,0xb4,0xb4], [0x51,0x97,0xc6,0xc6], 
	[0x23,0xcb,0xe8,0xe8], [0x7c,0xa1,0xdd,0xdd], [0x9c,0xe8,0x74,0x74], [0x21,0x3e,0x1f,0x1f], 
	[0xdd,0x96,0x4b,0x4b], [0xdc,0x61,0xbd,0xbd], [0x86,0x0d,0x8b,0x8b], [0x85,0x0f,0x8a,0x8a], 
	[0x90,0xe0,0x70,0x70], [0x42,0x7c,0x3e,0x3e], [0xc4,0x71,0xb5,0xb5], [0xaa,0xcc,0x66,0x66], 
	[0xd8,0x90,0x48,0x48], [0x05,0x06,0x03,0x03], [0x01,0xf7,0xf6,0xf6], [0x12,0x1c,0x0e,0x0e], 
	[0xa3,0xc2,0x61,0x61], [0x5f,0x6a,0x35,0x35], [0xf9,0xae,0x57,0x57], [0xd0,0x69,0xb9,0xb9], 
	[0x91,0x17,0x86,0x86], [0x58,0x99,0xc1,0xc1], [0x27,0x3a,0x1d,0x1d], [0xb9,0x27,0x9e,0x9e], 
	[0x38,0xd9,0xe1,0xe1], [0x13,0xeb,0xf8,0xf8], [0xb3,0x2b,0x98,0x98], [0x33,0x22,0x11,0x11], 
	[0xbb,0xd2,0x69,0x69], [0x70,0xa9,0xd9,0xd9], [0x89,0x07,0x8e,0x8e], [0xa7,0x33,0x94,0x94], 
	[0xb6,0x2d,0x9b,0x9b], [0x22,0x3c,0x1e,0x1e], [0x92,0x15,0x87,0x87], [0x20,0xc9,0xe9,0xe9], 
	[0x49,0x87,0xce,0xce], [0xff,0xaa,0x55,0x55], [0x78,0x50,0x28,0x28], [0x7a,0xa5,0xdf,0xdf], 
	[0x8f,0x03,0x8c,0x8c], [0xf8,0x59,0xa1,0xa1], [0x80,0x09,0x89,0x89], [0x17,0x1a,0x0d,0x0d], 
	[0xda,0x65,0xbf,0xbf], [0x31,0xd7,0xe6,0xe6], [0xc6,0x84,0x42,0x42], [0xb8,0xd0,0x68,0x68], 
	[0xc3,0x82,0x41,0x41], [0xb0,0x29,0x99,0x99], [0x77,0x5a,0x2d,0x2d], [0x11,0x1e,0x0f,0x0f], 
	[0xcb,0x7b,0xb0,0xb0], [0xfc,0xa8,0x54,0x54], [0xd6,0x6d,0xbb,0xbb], [0x3a,0x2c,0x16,0x16]
);

my @T3 = (
	[0x63,0xa5,0xc6,0x63], [0x7c,0x84,0xf8,0x7c], [0x77,0x99,0xee,0x77], [0x7b,0x8d,0xf6,0x7b], 
	[0xf2,0x0d,0xff,0xf2], [0x6b,0xbd,0xd6,0x6b], [0x6f,0xb1,0xde,0x6f], [0xc5,0x54,0x91,0xc5], 
	[0x30,0x50,0x60,0x30], [0x01,0x03,0x02,0x01], [0x67,0xa9,0xce,0x67], [0x2b,0x7d,0x56,0x2b], 
	[0xfe,0x19,0xe7,0xfe], [0xd7,0x62,0xb5,0xd7], [0xab,0xe6,0x4d,0xab], [0x76,0x9a,0xec,0x76], 
	[0xca,0x45,0x8f,0xca], [0x82,0x9d,0x1f,0x82], [0xc9,0x40,0x89,0xc9], [0x7d,0x87,0xfa,0x7d], 
	[0xfa,0x15,0xef,0xfa], [0x59,0xeb,0xb2,0x59], [0x47,0xc9,0x8e,0x47], [0xf0,0x0b,0xfb,0xf0], 
	[0xad,0xec,0x41,0xad], [0xd4,0x67,0xb3,0xd4], [0xa2,0xfd,0x5f,0xa2], [0xaf,0xea,0x45,0xaf], 
	[0x9c,0xbf,0x23,0x9c], [0xa4,0xf7,0x53,0xa4], [0x72,0x96,0xe4,0x72], [0xc0,0x5b,0x9b,0xc0], 
	[0xb7,0xc2,0x75,0xb7], [0xfd,0x1c,0xe1,0xfd], [0x93,0xae,0x3d,0x93], [0x26,0x6a,0x4c,0x26], 
	[0x36,0x5a,0x6c,0x36], [0x3f,0x41,0x7e,0x3f], [0xf7,0x02,0xf5,0xf7], [0xcc,0x4f,0x83,0xcc], 
	[0x34,0x5c,0x68,0x34], [0xa5,0xf4,0x51,0xa5], [0xe5,0x34,0xd1,0xe5], [0xf1,0x08,0xf9,0xf1], 
	[0x71,0x93,0xe2,0x71], [0xd8,0x73,0xab,0xd8], [0x31,0x53,0x62,0x31], [0x15,0x3f,0x2a,0x15], 
	[0x04,0x0c,0x08,0x04], [0xc7,0x52,0x95,0xc7], [0x23,0x65,0x46,0x23], [0xc3,0x5e,0x9d,0xc3], 
	[0x18,0x28,0x30,0x18], [0x96,0xa1,0x37,0x96], [0x05,0x0f,0x0a,0x05], [0x9a,0xb5,0x2f,0x9a], 
	[0x07,0x09,0x0e,0x07], [0x12,0x36,0x24,0x12], [0x80,0x9b,0x1b,0x80], [0xe2,0x3d,0xdf,0xe2], 
	[0xeb,0x26,0xcd,0xeb], [0x27,0x69,0x4e,0x27], [0xb2,0xcd,0x7f,0xb2], [0x75,0x9f,0xea,0x75], 
	[0x09,0x1b,0x12,0x09], [0x83,0x9e,0x1d,0x83], [0x2c,0x74,0x58,0x2c], [0x1a,0x2e,0x34,0x1a], 
	[0x1b,0x2d,0x36,0x1b], [0x6e,0xb2,0xdc,0x6e], [0x5a,0xee,0xb4,0x5a], [0xa0,0xfb,0x5b,0xa0], 
	[0x52,0xf6,0xa4,0x52], [0x3b,0x4d,0x76,0x3b], [0xd6,0x61,0xb7,0xd6], [0xb3,0xce,0x7d,0xb3], 
	[0x29,0x7b,0x52,0x29], [0xe3,0x3e,0xdd,0xe3], [0x2f,0x71,0x5e,0x2f], [0x84,0x97,0x13,0x84], 
	[0x53,0xf5,0xa6,0x53], [0xd1,0x68,0xb9,0xd1], [0x00,0x00,0x00,0x00], [0xed,0x2c,0xc1,0xed], 
	[0x20,0x60,0x40,0x20], [0xfc,0x1f,0xe3,0xfc], [0xb1,0xc8,0x79,0xb1], [0x5b,0xed,0xb6,0x5b], 
	[0x6a,0xbe,0xd4,0x6a], [0xcb,0x46,0x8d,0xcb], [0xbe,0xd9,0x67,0xbe], [0x39,0x4b,0x72,0x39], 
	[0x4a,0xde,0x94,0x4a], [0x4c,0xd4,0x98,0x4c], [0x58,0xe8,0xb0,0x58], [0xcf,0x4a,0x85,0xcf], 
	[0xd0,0x6b,0xbb,0xd0], [0xef,0x2a,0xc5,0xef], [0xaa,0xe5,0x4f,0xaa], [0xfb,0x16,0xed,0xfb], 
	[0x43,0xc5,0x86,0x43], [0x4d,0xd7,0x9a,0x4d], [0x33,0x55,0x66,0x33], [0x85,0x94,0x11,0x85], 
	[0x45,0xcf,0x8a,0x45], [0xf9,0x10,0xe9,0xf9], [0x02,0x06,0x04,0x02], [0x7f,0x81,0xfe,0x7f], 
	[0x50,0xf0,0xa0,0x50], [0x3c,0x44,0x78,0x3c], [0x9f,0xba,0x25,0x9f], [0xa8,0xe3,0x4b,0xa8], 
	[0x51,0xf3,0xa2,0x51], [0xa3,0xfe,0x5d,0xa3], [0x40,0xc0,0x80,0x40], [0x8f,0x8a,0x05,0x8f], 
	[0x92,0xad,0x3f,0x92], [0x9d,0xbc,0x21,0x9d], [0x38,0x48,0x70,0x38], [0xf5,0x04,0xf1,0xf5], 
	[0xbc,0xdf,0x63,0xbc], [0xb6,0xc1,0x77,0xb6], [0xda,0x75,0xaf,0xda], [0x21,0x63,0x42,0x21], 
	[0x10,0x30,0x20,0x10], [0xff,0x1a,0xe5,0xff], [0xf3,0x0e,0xfd,0xf3], [0xd2,0x6d,0xbf,0xd2], 
	[0xcd,0x4c,0x81,0xcd], [0x0c,0x14,0x18,0x0c], [0x13,0x35,0x26,0x13], [0xec,0x2f,0xc3,0xec], 
	[0x5f,0xe1,0xbe,0x5f], [0x97,0xa2,0x35,0x97], [0x44,0xcc,0x88,0x44], [0x17,0x39,0x2e,0x17], 
	[0xc4,0x57,0x93,0xc4], [0xa7,0xf2,0x55,0xa7], [0x7e,0x82,0xfc,0x7e], [0x3d,0x47,0x7a,0x3d], 
	[0x64,0xac,0xc8,0x64], [0x5d,0xe7,0xba,0x5d], [0x19,0x2b,0x32,0x19], [0x73,0x95,0xe6,0x73], 
	[0x60,0xa0,0xc0,0x60], [0x81,0x98,0x19,0x81], [0x4f,0xd1,0x9e,0x4f], [0xdc,0x7f,0xa3,0xdc], 
	[0x22,0x66,0x44,0x22], [0x2a,0x7e,0x54,0x2a], [0x90,0xab,0x3b,0x90], [0x88,0x83,0x0b,0x88], 
	[0x46,0xca,0x8c,0x46], [0xee,0x29,0xc7,0xee], [0xb8,0xd3,0x6b,0xb8], [0x14,0x3c,0x28,0x14], 
	[0xde,0x79,0xa7,0xde], [0x5e,0xe2,0xbc,0x5e], [0x0b,0x1d,0x16,0x0b], [0xdb,0x76,0xad,0xdb], 
	[0xe0,0x3b,0xdb,0xe0], [0x32,0x56,0x64,0x32], [0x3a,0x4e,0x74,0x3a], [0x0a,0x1e,0x14,0x0a], 
	[0x49,0xdb,0x92,0x49], [0x06,0x0a,0x0c,0x06], [0x24,0x6c,0x48,0x24], [0x5c,0xe4,0xb8,0x5c], 
	[0xc2,0x5d,0x9f,0xc2], [0xd3,0x6e,0xbd,0xd3], [0xac,0xef,0x43,0xac], [0x62,0xa6,0xc4,0x62], 
	[0x91,0xa8,0x39,0x91], [0x95,0xa4,0x31,0x95], [0xe4,0x37,0xd3,0xe4], [0x79,0x8b,0xf2,0x79], 
	[0xe7,0x32,0xd5,0xe7], [0xc8,0x43,0x8b,0xc8], [0x37,0x59,0x6e,0x37], [0x6d,0xb7,0xda,0x6d], 
	[0x8d,0x8c,0x01,0x8d], [0xd5,0x64,0xb1,0xd5], [0x4e,0xd2,0x9c,0x4e], [0xa9,0xe0,0x49,0xa9], 
	[0x6c,0xb4,0xd8,0x6c], [0x56,0xfa,0xac,0x56], [0xf4,0x07,0xf3,0xf4], [0xea,0x25,0xcf,0xea], 
	[0x65,0xaf,0xca,0x65], [0x7a,0x8e,0xf4,0x7a], [0xae,0xe9,0x47,0xae], [0x08,0x18,0x10,0x08], 
	[0xba,0xd5,0x6f,0xba], [0x78,0x88,0xf0,0x78], [0x25,0x6f,0x4a,0x25], [0x2e,0x72,0x5c,0x2e], 
	[0x1c,0x24,0x38,0x1c], [0xa6,0xf1,0x57,0xa6], [0xb4,0xc7,0x73,0xb4], [0xc6,0x51,0x97,0xc6], 
	[0xe8,0x23,0xcb,0xe8], [0xdd,0x7c,0xa1,0xdd], [0x74,0x9c,0xe8,0x74], [0x1f,0x21,0x3e,0x1f], 
	[0x4b,0xdd,0x96,0x4b], [0xbd,0xdc,0x61,0xbd], [0x8b,0x86,0x0d,0x8b], [0x8a,0x85,0x0f,0x8a], 
	[0x70,0x90,0xe0,0x70], [0x3e,0x42,0x7c,0x3e], [0xb5,0xc4,0x71,0xb5], [0x66,0xaa,0xcc,0x66], 
	[0x48,0xd8,0x90,0x48], [0x03,0x05,0x06,0x03], [0xf6,0x01,0xf7,0xf6], [0x0e,0x12,0x1c,0x0e], 
	[0x61,0xa3,0xc2,0x61], [0x35,0x5f,0x6a,0x35], [0x57,0xf9,0xae,0x57], [0xb9,0xd0,0x69,0xb9], 
	[0x86,0x91,0x17,0x86], [0xc1,0x58,0x99,0xc1], [0x1d,0x27,0x3a,0x1d], [0x9e,0xb9,0x27,0x9e], 
	[0xe1,0x38,0xd9,0xe1], [0xf8,0x13,0xeb,0xf8], [0x98,0xb3,0x2b,0x98], [0x11,0x33,0x22,0x11], 
	[0x69,0xbb,0xd2,0x69], [0xd9,0x70,0xa9,0xd9], [0x8e,0x89,0x07,0x8e], [0x94,0xa7,0x33,0x94], 
	[0x9b,0xb6,0x2d,0x9b], [0x1e,0x22,0x3c,0x1e], [0x87,0x92,0x15,0x87], [0xe9,0x20,0xc9,0xe9], 
	[0xce,0x49,0x87,0xce], [0x55,0xff,0xaa,0x55], [0x28,0x78,0x50,0x28], [0xdf,0x7a,0xa5,0xdf], 
	[0x8c,0x8f,0x03,0x8c], [0xa1,0xf8,0x59,0xa1], [0x89,0x80,0x09,0x89], [0x0d,0x17,0x1a,0x0d], 
	[0xbf,0xda,0x65,0xbf], [0xe6,0x31,0xd7,0xe6], [0x42,0xc6,0x84,0x42], [0x68,0xb8,0xd0,0x68], 
	[0x41,0xc3,0x82,0x41], [0x99,0xb0,0x29,0x99], [0x2d,0x77,0x5a,0x2d], [0x0f,0x11,0x1e,0x0f], 
	[0xb0,0xcb,0x7b,0xb0], [0x54,0xfc,0xa8,0x54], [0xbb,0xd6,0x6d,0xbb], [0x16,0x3a,0x2c,0x16]
);

my @T4 = (
	[0x63,0x63,0xa5,0xc6], [0x7c,0x7c,0x84,0xf8], [0x77,0x77,0x99,0xee], [0x7b,0x7b,0x8d,0xf6], 
	[0xf2,0xf2,0x0d,0xff], [0x6b,0x6b,0xbd,0xd6], [0x6f,0x6f,0xb1,0xde], [0xc5,0xc5,0x54,0x91], 
	[0x30,0x30,0x50,0x60], [0x01,0x01,0x03,0x02], [0x67,0x67,0xa9,0xce], [0x2b,0x2b,0x7d,0x56], 
	[0xfe,0xfe,0x19,0xe7], [0xd7,0xd7,0x62,0xb5], [0xab,0xab,0xe6,0x4d], [0x76,0x76,0x9a,0xec], 
	[0xca,0xca,0x45,0x8f], [0x82,0x82,0x9d,0x1f], [0xc9,0xc9,0x40,0x89], [0x7d,0x7d,0x87,0xfa], 
	[0xfa,0xfa,0x15,0xef], [0x59,0x59,0xeb,0xb2], [0x47,0x47,0xc9,0x8e], [0xf0,0xf0,0x0b,0xfb], 
	[0xad,0xad,0xec,0x41], [0xd4,0xd4,0x67,0xb3], [0xa2,0xa2,0xfd,0x5f], [0xaf,0xaf,0xea,0x45], 
	[0x9c,0x9c,0xbf,0x23], [0xa4,0xa4,0xf7,0x53], [0x72,0x72,0x96,0xe4], [0xc0,0xc0,0x5b,0x9b], 
	[0xb7,0xb7,0xc2,0x75], [0xfd,0xfd,0x1c,0xe1], [0x93,0x93,0xae,0x3d], [0x26,0x26,0x6a,0x4c], 
	[0x36,0x36,0x5a,0x6c], [0x3f,0x3f,0x41,0x7e], [0xf7,0xf7,0x02,0xf5], [0xcc,0xcc,0x4f,0x83], 
	[0x34,0x34,0x5c,0x68], [0xa5,0xa5,0xf4,0x51], [0xe5,0xe5,0x34,0xd1], [0xf1,0xf1,0x08,0xf9], 
	[0x71,0x71,0x93,0xe2], [0xd8,0xd8,0x73,0xab], [0x31,0x31,0x53,0x62], [0x15,0x15,0x3f,0x2a], 
	[0x04,0x04,0x0c,0x08], [0xc7,0xc7,0x52,0x95], [0x23,0x23,0x65,0x46], [0xc3,0xc3,0x5e,0x9d], 
	[0x18,0x18,0x28,0x30], [0x96,0x96,0xa1,0x37], [0x05,0x05,0x0f,0x0a], [0x9a,0x9a,0xb5,0x2f], 
	[0x07,0x07,0x09,0x0e], [0x12,0x12,0x36,0x24], [0x80,0x80,0x9b,0x1b], [0xe2,0xe2,0x3d,0xdf], 
	[0xeb,0xeb,0x26,0xcd], [0x27,0x27,0x69,0x4e], [0xb2,0xb2,0xcd,0x7f], [0x75,0x75,0x9f,0xea], 
	[0x09,0x09,0x1b,0x12], [0x83,0x83,0x9e,0x1d], [0x2c,0x2c,0x74,0x58], [0x1a,0x1a,0x2e,0x34], 
	[0x1b,0x1b,0x2d,0x36], [0x6e,0x6e,0xb2,0xdc], [0x5a,0x5a,0xee,0xb4], [0xa0,0xa0,0xfb,0x5b], 
	[0x52,0x52,0xf6,0xa4], [0x3b,0x3b,0x4d,0x76], [0xd6,0xd6,0x61,0xb7], [0xb3,0xb3,0xce,0x7d], 
	[0x29,0x29,0x7b,0x52], [0xe3,0xe3,0x3e,0xdd], [0x2f,0x2f,0x71,0x5e], [0x84,0x84,0x97,0x13], 
	[0x53,0x53,0xf5,0xa6], [0xd1,0xd1,0x68,0xb9], [0x00,0x00,0x00,0x00], [0xed,0xed,0x2c,0xc1], 
	[0x20,0x20,0x60,0x40], [0xfc,0xfc,0x1f,0xe3], [0xb1,0xb1,0xc8,0x79], [0x5b,0x5b,0xed,0xb6], 
	[0x6a,0x6a,0xbe,0xd4], [0xcb,0xcb,0x46,0x8d], [0xbe,0xbe,0xd9,0x67], [0x39,0x39,0x4b,0x72], 
	[0x4a,0x4a,0xde,0x94], [0x4c,0x4c,0xd4,0x98], [0x58,0x58,0xe8,0xb0], [0xcf,0xcf,0x4a,0x85], 
	[0xd0,0xd0,0x6b,0xbb], [0xef,0xef,0x2a,0xc5], [0xaa,0xaa,0xe5,0x4f], [0xfb,0xfb,0x16,0xed], 
	[0x43,0x43,0xc5,0x86], [0x4d,0x4d,0xd7,0x9a], [0x33,0x33,0x55,0x66], [0x85,0x85,0x94,0x11], 
	[0x45,0x45,0xcf,0x8a], [0xf9,0xf9,0x10,0xe9], [0x02,0x02,0x06,0x04], [0x7f,0x7f,0x81,0xfe], 
	[0x50,0x50,0xf0,0xa0], [0x3c,0x3c,0x44,0x78], [0x9f,0x9f,0xba,0x25], [0xa8,0xa8,0xe3,0x4b], 
	[0x51,0x51,0xf3,0xa2], [0xa3,0xa3,0xfe,0x5d], [0x40,0x40,0xc0,0x80], [0x8f,0x8f,0x8a,0x05], 
	[0x92,0x92,0xad,0x3f], [0x9d,0x9d,0xbc,0x21], [0x38,0x38,0x48,0x70], [0xf5,0xf5,0x04,0xf1], 
	[0xbc,0xbc,0xdf,0x63], [0xb6,0xb6,0xc1,0x77], [0xda,0xda,0x75,0xaf], [0x21,0x21,0x63,0x42], 
	[0x10,0x10,0x30,0x20], [0xff,0xff,0x1a,0xe5], [0xf3,0xf3,0x0e,0xfd], [0xd2,0xd2,0x6d,0xbf], 
	[0xcd,0xcd,0x4c,0x81], [0x0c,0x0c,0x14,0x18], [0x13,0x13,0x35,0x26], [0xec,0xec,0x2f,0xc3], 
	[0x5f,0x5f,0xe1,0xbe], [0x97,0x97,0xa2,0x35], [0x44,0x44,0xcc,0x88], [0x17,0x17,0x39,0x2e], 
	[0xc4,0xc4,0x57,0x93], [0xa7,0xa7,0xf2,0x55], [0x7e,0x7e,0x82,0xfc], [0x3d,0x3d,0x47,0x7a], 
	[0x64,0x64,0xac,0xc8], [0x5d,0x5d,0xe7,0xba], [0x19,0x19,0x2b,0x32], [0x73,0x73,0x95,0xe6], 
	[0x60,0x60,0xa0,0xc0], [0x81,0x81,0x98,0x19], [0x4f,0x4f,0xd1,0x9e], [0xdc,0xdc,0x7f,0xa3], 
	[0x22,0x22,0x66,0x44], [0x2a,0x2a,0x7e,0x54], [0x90,0x90,0xab,0x3b], [0x88,0x88,0x83,0x0b], 
	[0x46,0x46,0xca,0x8c], [0xee,0xee,0x29,0xc7], [0xb8,0xb8,0xd3,0x6b], [0x14,0x14,0x3c,0x28], 
	[0xde,0xde,0x79,0xa7], [0x5e,0x5e,0xe2,0xbc], [0x0b,0x0b,0x1d,0x16], [0xdb,0xdb,0x76,0xad], 
	[0xe0,0xe0,0x3b,0xdb], [0x32,0x32,0x56,0x64], [0x3a,0x3a,0x4e,0x74], [0x0a,0x0a,0x1e,0x14], 
	[0x49,0x49,0xdb,0x92], [0x06,0x06,0x0a,0x0c], [0x24,0x24,0x6c,0x48], [0x5c,0x5c,0xe4,0xb8], 
	[0xc2,0xc2,0x5d,0x9f], [0xd3,0xd3,0x6e,0xbd], [0xac,0xac,0xef,0x43], [0x62,0x62,0xa6,0xc4], 
	[0x91,0x91,0xa8,0x39], [0x95,0x95,0xa4,0x31], [0xe4,0xe4,0x37,0xd3], [0x79,0x79,0x8b,0xf2], 
	[0xe7,0xe7,0x32,0xd5], [0xc8,0xc8,0x43,0x8b], [0x37,0x37,0x59,0x6e], [0x6d,0x6d,0xb7,0xda], 
	[0x8d,0x8d,0x8c,0x01], [0xd5,0xd5,0x64,0xb1], [0x4e,0x4e,0xd2,0x9c], [0xa9,0xa9,0xe0,0x49], 
	[0x6c,0x6c,0xb4,0xd8], [0x56,0x56,0xfa,0xac], [0xf4,0xf4,0x07,0xf3], [0xea,0xea,0x25,0xcf], 
	[0x65,0x65,0xaf,0xca], [0x7a,0x7a,0x8e,0xf4], [0xae,0xae,0xe9,0x47], [0x08,0x08,0x18,0x10], 
	[0xba,0xba,0xd5,0x6f], [0x78,0x78,0x88,0xf0], [0x25,0x25,0x6f,0x4a], [0x2e,0x2e,0x72,0x5c], 
	[0x1c,0x1c,0x24,0x38], [0xa6,0xa6,0xf1,0x57], [0xb4,0xb4,0xc7,0x73], [0xc6,0xc6,0x51,0x97], 
	[0xe8,0xe8,0x23,0xcb], [0xdd,0xdd,0x7c,0xa1], [0x74,0x74,0x9c,0xe8], [0x1f,0x1f,0x21,0x3e], 
	[0x4b,0x4b,0xdd,0x96], [0xbd,0xbd,0xdc,0x61], [0x8b,0x8b,0x86,0x0d], [0x8a,0x8a,0x85,0x0f], 
	[0x70,0x70,0x90,0xe0], [0x3e,0x3e,0x42,0x7c], [0xb5,0xb5,0xc4,0x71], [0x66,0x66,0xaa,0xcc], 
	[0x48,0x48,0xd8,0x90], [0x03,0x03,0x05,0x06], [0xf6,0xf6,0x01,0xf7], [0x0e,0x0e,0x12,0x1c], 
	[0x61,0x61,0xa3,0xc2], [0x35,0x35,0x5f,0x6a], [0x57,0x57,0xf9,0xae], [0xb9,0xb9,0xd0,0x69], 
	[0x86,0x86,0x91,0x17], [0xc1,0xc1,0x58,0x99], [0x1d,0x1d,0x27,0x3a], [0x9e,0x9e,0xb9,0x27], 
	[0xe1,0xe1,0x38,0xd9], [0xf8,0xf8,0x13,0xeb], [0x98,0x98,0xb3,0x2b], [0x11,0x11,0x33,0x22], 
	[0x69,0x69,0xbb,0xd2], [0xd9,0xd9,0x70,0xa9], [0x8e,0x8e,0x89,0x07], [0x94,0x94,0xa7,0x33], 
	[0x9b,0x9b,0xb6,0x2d], [0x1e,0x1e,0x22,0x3c], [0x87,0x87,0x92,0x15], [0xe9,0xe9,0x20,0xc9], 
	[0xce,0xce,0x49,0x87], [0x55,0x55,0xff,0xaa], [0x28,0x28,0x78,0x50], [0xdf,0xdf,0x7a,0xa5], 
	[0x8c,0x8c,0x8f,0x03], [0xa1,0xa1,0xf8,0x59], [0x89,0x89,0x80,0x09], [0x0d,0x0d,0x17,0x1a], 
	[0xbf,0xbf,0xda,0x65], [0xe6,0xe6,0x31,0xd7], [0x42,0x42,0xc6,0x84], [0x68,0x68,0xb8,0xd0], 
	[0x41,0x41,0xc3,0x82], [0x99,0x99,0xb0,0x29], [0x2d,0x2d,0x77,0x5a], [0x0f,0x0f,0x11,0x1e], 
	[0xb0,0xb0,0xcb,0x7b], [0x54,0x54,0xfc,0xa8], [0xbb,0xbb,0xd6,0x6d], [0x16,0x16,0x3a,0x2c]
);

my @T5 = (
	[0x51,0xf4,0xa7,0x50], [0x7e,0x41,0x65,0x53], [0x1a,0x17,0xa4,0xc3], [0x3a,0x27,0x5e,0x96], 
	[0x3b,0xab,0x6b,0xcb], [0x1f,0x9d,0x45,0xf1], [0xac,0xfa,0x58,0xab], [0x4b,0xe3,0x03,0x93], 
	[0x20,0x30,0xfa,0x55], [0xad,0x76,0x6d,0xf6], [0x88,0xcc,0x76,0x91], [0xf5,0x02,0x4c,0x25], 
	[0x4f,0xe5,0xd7,0xfc], [0xc5,0x2a,0xcb,0xd7], [0x26,0x35,0x44,0x80], [0xb5,0x62,0xa3,0x8f], 
	[0xde,0xb1,0x5a,0x49], [0x25,0xba,0x1b,0x67], [0x45,0xea,0x0e,0x98], [0x5d,0xfe,0xc0,0xe1], 
	[0xc3,0x2f,0x75,0x02], [0x81,0x4c,0xf0,0x12], [0x8d,0x46,0x97,0xa3], [0x6b,0xd3,0xf9,0xc6], 
	[0x03,0x8f,0x5f,0xe7], [0x15,0x92,0x9c,0x95], [0xbf,0x6d,0x7a,0xeb], [0x95,0x52,0x59,0xda], 
	[0xd4,0xbe,0x83,0x2d], [0x58,0x74,0x21,0xd3], [0x49,0xe0,0x69,0x29], [0x8e,0xc9,0xc8,0x44], 
	[0x75,0xc2,0x89,0x6a], [0xf4,0x8e,0x79,0x78], [0x99,0x58,0x3e,0x6b], [0x27,0xb9,0x71,0xdd], 
	[0xbe,0xe1,0x4f,0xb6], [0xf0,0x88,0xad,0x17], [0xc9,0x20,0xac,0x66], [0x7d,0xce,0x3a,0xb4], 
	[0x63,0xdf,0x4a,0x18], [0xe5,0x1a,0x31,0x82], [0x97,0x51,0x33,0x60], [0x62,0x53,0x7f,0x45], 
	[0xb1,0x64,0x77,0xe0], [0xbb,0x6b,0xae,0x84], [0xfe,0x81,0xa0,0x1c], [0xf9,0x08,0x2b,0x94], 
	[0x70,0x48,0x68,0x58], [0x8f,0x45,0xfd,0x19], [0x94,0xde,0x6c,0x87], [0x52,0x7b,0xf8,0xb7], 
	[0xab,0x73,0xd3,0x23], [0x72,0x4b,0x02,0xe2], [0xe3,0x1f,0x8f,0x57], [0x66,0x55,0xab,0x2a], 
	[0xb2,0xeb,0x28,0x07], [0x2f,0xb5,0xc2,0x03], [0x86,0xc5,0x7b,0x9a], [0xd3,0x37,0x08,0xa5], 
	[0x30,0x28,0x87,0xf2], [0x23,0xbf,0xa5,0xb2], [0x02,0x03,0x6a,0xba], [0xed,0x16,0x82,0x5c], 
	[0x8a,0xcf,0x1c,0x2b], [0xa7,0x79,0xb4,0x92], [0xf3,0x07,0xf2,0xf0], [0x4e,0x69,0xe2,0xa1], 
	[0x65,0xda,0xf4,0xcd], [0x06,0x05,0xbe,0xd5], [0xd1,0x34,0x62,0x1f], [0xc4,0xa6,0xfe,0x8a], 
	[0x34,0x2e,0x53,0x9d], [0xa2,0xf3,0x55,0xa0], [0x05,0x8a,0xe1,0x32], [0xa4,0xf6,0xeb,0x75], 
	[0x0b,0x83,0xec,0x39], [0x40,0x60,0xef,0xaa], [0x5e,0x71,0x9f,0x06], [0xbd,0x6e,0x10,0x51], 
	[0x3e,0x21,0x8a,0xf9], [0x96,0xdd,0x06,0x3d], [0xdd,0x3e,0x05,0xae], [0x4d,0xe6,0xbd,0x46], 
	[0x91,0x54,0x8d,0xb5], [0x71,0xc4,0x5d,0x05], [0x04,0x06,0xd4,0x6f], [0x60,0x50,0x15,0xff], 
	[0x19,0x98,0xfb,0x24], [0xd6,0xbd,0xe9,0x97], [0x89,0x40,0x43,0xcc], [0x67,0xd9,0x9e,0x77], 
	[0xb0,0xe8,0x42,0xbd], [0x07,0x89,0x8b,0x88], [0xe7,0x19,0x5b,0x38], [0x79,0xc8,0xee,0xdb], 
	[0xa1,0x7c,0x0a,0x47], [0x7c,0x42,0x0f,0xe9], [0xf8,0x84,0x1e,0xc9], [0x00,0x00,0x00,0x00], 
	[0x09,0x80,0x86,0x83], [0x32,0x2b,0xed,0x48], [0x1e,0x11,0x70,0xac], [0x6c,0x5a,0x72,0x4e], 
	[0xfd,0x0e,0xff,0xfb], [0x0f,0x85,0x38,0x56], [0x3d,0xae,0xd5,0x1e], [0x36,0x2d,0x39,0x27], 
	[0x0a,0x0f,0xd9,0x64], [0x68,0x5c,0xa6,0x21], [0x9b,0x5b,0x54,0xd1], [0x24,0x36,0x2e,0x3a], 
	[0x0c,0x0a,0x67,0xb1], [0x93,0x57,0xe7,0x0f], [0xb4,0xee,0x96,0xd2], [0x1b,0x9b,0x91,0x9e], 
	[0x80,0xc0,0xc5,0x4f], [0x61,0xdc,0x20,0xa2], [0x5a,0x77,0x4b,0x69], [0x1c,0x12,0x1a,0x16], 
	[0xe2,0x93,0xba,0x0a], [0xc0,0xa0,0x2a,0xe5], [0x3c,0x22,0xe0,0x43], [0x12,0x1b,0x17,0x1d], 
	[0x0e,0x09,0x0d,0x0b], [0xf2,0x8b,0xc7,0xad], [0x2d,0xb6,0xa8,0xb9], [0x14,0x1e,0xa9,0xc8], 
	[0x57,0xf1,0x19,0x85], [0xaf,0x75,0x07,0x4c], [0xee,0x99,0xdd,0xbb], [0xa3,0x7f,0x60,0xfd], 
	[0xf7,0x01,0x26,0x9f], [0x5c,0x72,0xf5,0xbc], [0x44,0x66,0x3b,0xc5], [0x5b,0xfb,0x7e,0x34], 
	[0x8b,0x43,0x29,0x76], [0xcb,0x23,0xc6,0xdc], [0xb6,0xed,0xfc,0x68], [0xb8,0xe4,0xf1,0x63], 
	[0xd7,0x31,0xdc,0xca], [0x42,0x63,0x85,0x10], [0x13,0x97,0x22,0x40], [0x84,0xc6,0x11,0x20], 
	[0x85,0x4a,0x24,0x7d], [0xd2,0xbb,0x3d,0xf8], [0xae,0xf9,0x32,0x11], [0xc7,0x29,0xa1,0x6d], 
	[0x1d,0x9e,0x2f,0x4b], [0xdc,0xb2,0x30,0xf3], [0x0d,0x86,0x52,0xec], [0x77,0xc1,0xe3,0xd0], 
	[0x2b,0xb3,0x16,0x6c], [0xa9,0x70,0xb9,0x99], [0x11,0x94,0x48,0xfa], [0x47,0xe9,0x64,0x22], 
	[0xa8,0xfc,0x8c,0xc4], [0xa0,0xf0,0x3f,0x1a], [0x56,0x7d,0x2c,0xd8], [0x22,0x33,0x90,0xef], 
	[0x87,0x49,0x4e,0xc7], [0xd9,0x38,0xd1,0xc1], [0x8c,0xca,0xa2,0xfe], [0x98,0xd4,0x0b,0x36], 
	[0xa6,0xf5,0x81,0xcf], [0xa5,0x7a,0xde,0x28], [0xda,0xb7,0x8e,0x26], [0x3f,0xad,0xbf,0xa4], 
	[0x2c,0x3a,0x9d,0xe4], [0x50,0x78,0x92,0x0d], [0x6a,0x5f,0xcc,0x9b], [0x54,0x7e,0x46,0x62], 
	[0xf6,0x8d,0x13,0xc2], [0x90,0xd8,0xb8,0xe8], [0x2e,0x39,0xf7,0x5e], [0x82,0xc3,0xaf,0xf5], 
	[0x9f,0x5d,0x80,0xbe], [0x69,0xd0,0x93,0x7c], [0x6f,0xd5,0x2d,0xa9], [0xcf,0x25,0x12,0xb3], 
	[0xc8,0xac,0x99,0x3b], [0x10,0x18,0x7d,0xa7], [0xe8,0x9c,0x63,0x6e], [0xdb,0x3b,0xbb,0x7b], 
	[0xcd,0x26,0x78,0x09], [0x6e,0x59,0x18,0xf4], [0xec,0x9a,0xb7,0x01], [0x83,0x4f,0x9a,0xa8], 
	[0xe6,0x95,0x6e,0x65], [0xaa,0xff,0xe6,0x7e], [0x21,0xbc,0xcf,0x08], [0xef,0x15,0xe8,0xe6], 
	[0xba,0xe7,0x9b,0xd9], [0x4a,0x6f,0x36,0xce], [0xea,0x9f,0x09,0xd4], [0x29,0xb0,0x7c,0xd6], 
	[0x31,0xa4,0xb2,0xaf], [0x2a,0x3f,0x23,0x31], [0xc6,0xa5,0x94,0x30], [0x35,0xa2,0x66,0xc0], 
	[0x74,0x4e,0xbc,0x37], [0xfc,0x82,0xca,0xa6], [0xe0,0x90,0xd0,0xb0], [0x33,0xa7,0xd8,0x15], 
	[0xf1,0x04,0x98,0x4a], [0x41,0xec,0xda,0xf7], [0x7f,0xcd,0x50,0x0e], [0x17,0x91,0xf6,0x2f], 
	[0x76,0x4d,0xd6,0x8d], [0x43,0xef,0xb0,0x4d], [0xcc,0xaa,0x4d,0x54], [0xe4,0x96,0x04,0xdf], 
	[0x9e,0xd1,0xb5,0xe3], [0x4c,0x6a,0x88,0x1b], [0xc1,0x2c,0x1f,0xb8], [0x46,0x65,0x51,0x7f], 
	[0x9d,0x5e,0xea,0x04], [0x01,0x8c,0x35,0x5d], [0xfa,0x87,0x74,0x73], [0xfb,0x0b,0x41,0x2e], 
	[0xb3,0x67,0x1d,0x5a], [0x92,0xdb,0xd2,0x52], [0xe9,0x10,0x56,0x33], [0x6d,0xd6,0x47,0x13], 
	[0x9a,0xd7,0x61,0x8c], [0x37,0xa1,0x0c,0x7a], [0x59,0xf8,0x14,0x8e], [0xeb,0x13,0x3c,0x89], 
	[0xce,0xa9,0x27,0xee], [0xb7,0x61,0xc9,0x35], [0xe1,0x1c,0xe5,0xed], [0x7a,0x47,0xb1,0x3c], 
	[0x9c,0xd2,0xdf,0x59], [0x55,0xf2,0x73,0x3f], [0x18,0x14,0xce,0x79], [0x73,0xc7,0x37,0xbf], 
	[0x53,0xf7,0xcd,0xea], [0x5f,0xfd,0xaa,0x5b], [0xdf,0x3d,0x6f,0x14], [0x78,0x44,0xdb,0x86], 
	[0xca,0xaf,0xf3,0x81], [0xb9,0x68,0xc4,0x3e], [0x38,0x24,0x34,0x2c], [0xc2,0xa3,0x40,0x5f], 
	[0x16,0x1d,0xc3,0x72], [0xbc,0xe2,0x25,0x0c], [0x28,0x3c,0x49,0x8b], [0xff,0x0d,0x95,0x41], 
	[0x39,0xa8,0x01,0x71], [0x08,0x0c,0xb3,0xde], [0xd8,0xb4,0xe4,0x9c], [0x64,0x56,0xc1,0x90], 
	[0x7b,0xcb,0x84,0x61], [0xd5,0x32,0xb6,0x70], [0x48,0x6c,0x5c,0x74], [0xd0,0xb8,0x57,0x42]
);

my @T6 = (
	[0x50,0x51,0xf4,0xa7], [0x53,0x7e,0x41,0x65], [0xc3,0x1a,0x17,0xa4], [0x96,0x3a,0x27,0x5e], 
	[0xcb,0x3b,0xab,0x6b], [0xf1,0x1f,0x9d,0x45], [0xab,0xac,0xfa,0x58], [0x93,0x4b,0xe3,0x03], 
	[0x55,0x20,0x30,0xfa], [0xf6,0xad,0x76,0x6d], [0x91,0x88,0xcc,0x76], [0x25,0xf5,0x02,0x4c], 
	[0xfc,0x4f,0xe5,0xd7], [0xd7,0xc5,0x2a,0xcb], [0x80,0x26,0x35,0x44], [0x8f,0xb5,0x62,0xa3], 
	[0x49,0xde,0xb1,0x5a], [0x67,0x25,0xba,0x1b], [0x98,0x45,0xea,0x0e], [0xe1,0x5d,0xfe,0xc0], 
	[0x02,0xc3,0x2f,0x75], [0x12,0x81,0x4c,0xf0], [0xa3,0x8d,0x46,0x97], [0xc6,0x6b,0xd3,0xf9], 
	[0xe7,0x03,0x8f,0x5f], [0x95,0x15,0x92,0x9c], [0xeb,0xbf,0x6d,0x7a], [0xda,0x95,0x52,0x59], 
	[0x2d,0xd4,0xbe,0x83], [0xd3,0x58,0x74,0x21], [0x29,0x49,0xe0,0x69], [0x44,0x8e,0xc9,0xc8], 
	[0x6a,0x75,0xc2,0x89], [0x78,0xf4,0x8e,0x79], [0x6b,0x99,0x58,0x3e], [0xdd,0x27,0xb9,0x71], 
	[0xb6,0xbe,0xe1,0x4f], [0x17,0xf0,0x88,0xad], [0x66,0xc9,0x20,0xac], [0xb4,0x7d,0xce,0x3a], 
	[0x18,0x63,0xdf,0x4a], [0x82,0xe5,0x1a,0x31], [0x60,0x97,0x51,0x33], [0x45,0x62,0x53,0x7f], 
	[0xe0,0xb1,0x64,0x77], [0x84,0xbb,0x6b,0xae], [0x1c,0xfe,0x81,0xa0], [0x94,0xf9,0x08,0x2b], 
	[0x58,0x70,0x48,0x68], [0x19,0x8f,0x45,0xfd], [0x87,0x94,0xde,0x6c], [0xb7,0x52,0x7b,0xf8], 
	[0x23,0xab,0x73,0xd3], [0xe2,0x72,0x4b,0x02], [0x57,0xe3,0x1f,0x8f], [0x2a,0x66,0x55,0xab], 
	[0x07,0xb2,0xeb,0x28], [0x03,0x2f,0xb5,0xc2], [0x9a,0x86,0xc5,0x7b], [0xa5,0xd3,0x37,0x08], 
	[0xf2,0x30,0x28,0x87], [0xb2,0x23,0xbf,0xa5], [0xba,0x02,0x03,0x6a], [0x5c,0xed,0x16,0x82], 
	[0x2b,0x8a,0xcf,0x1c], [0x92,0xa7,0x79,0xb4], [0xf0,0xf3,0x07,0xf2], [0xa1,0x4e,0x69,0xe2], 
	[0xcd,0x65,0xda,0xf4], [0xd5,0x06,0x05,0xbe], [0x1f,0xd1,0x34,0x62], [0x8a,0xc4,0xa6,0xfe], 
	[0x9d,0x34,0x2e,0x53], [0xa0,0xa2,0xf3,0x55], [0x32,0x05,0x8a,0xe1], [0x75,0xa4,0xf6,0xeb], 
	[0x39,0x0b,0x83,0xec], [0xaa,0x40,0x60,0xef], [0x06,0x5e,0x71,0x9f], [0x51,0xbd,0x6e,0x10], 
	[0xf9,0x3e,0x21,0x8a], [0x3d,0x96,0xdd,0x06], [0xae,0xdd,0x3e,0x05], [0x46,0x4d,0xe6,0xbd], 
	[0xb5,0x91,0x54,0x8d], [0x05,0x71,0xc4,0x5d], [0x6f,0x04,0x06,0xd4], [0xff,0x60,0x50,0x15], 
	[0x24,0x19,0x98,0xfb], [0x97,0xd6,0xbd,0xe9], [0xcc,0x89,0x40,0x43], [0x77,0x67,0xd9,0x9e], 
	[0xbd,0xb0,0xe8,0x42], [0x88,0x07,0x89,0x8b], [0x38,0xe7,0x19,0x5b], [0xdb,0x79,0xc8,0xee], 
	[0x47,0xa1,0x7c,0x0a], [0xe9,0x7c,0x42,0x0f], [0xc9,0xf8,0x84,0x1e], [0x00,0x00,0x00,0x00], 
	[0x83,0x09,0x80,0x86], [0x48,0x32,0x2b,0xed], [0xac,0x1e,0x11,0x70], [0x4e,0x6c,0x5a,0x72], 
	[0xfb,0xfd,0x0e,0xff], [0x56,0x0f,0x85,0x38], [0x1e,0x3d,0xae,0xd5], [0x27,0x36,0x2d,0x39], 
	[0x64,0x0a,0x0f,0xd9], [0x21,0x68,0x5c,0xa6], [0xd1,0x9b,0x5b,0x54], [0x3a,0x24,0x36,0x2e], 
	[0xb1,0x0c,0x0a,0x67], [0x0f,0x93,0x57,0xe7], [0xd2,0xb4,0xee,0x96], [0x9e,0x1b,0x9b,0x91], 
	[0x4f,0x80,0xc0,0xc5], [0xa2,0x61,0xdc,0x20], [0x69,0x5a,0x77,0x4b], [0x16,0x1c,0x12,0x1a], 
	[0x0a,0xe2,0x93,0xba], [0xe5,0xc0,0xa0,0x2a], [0x43,0x3c,0x22,0xe0], [0x1d,0x12,0x1b,0x17], 
	[0x0b,0x0e,0x09,0x0d], [0xad,0xf2,0x8b,0xc7], [0xb9,0x2d,0xb6,0xa8], [0xc8,0x14,0x1e,0xa9], 
	[0x85,0x57,0xf1,0x19], [0x4c,0xaf,0x75,0x07], [0xbb,0xee,0x99,0xdd], [0xfd,0xa3,0x7f,0x60], 
	[0x9f,0xf7,0x01,0x26], [0xbc,0x5c,0x72,0xf5], [0xc5,0x44,0x66,0x3b], [0x34,0x5b,0xfb,0x7e], 
	[0x76,0x8b,0x43,0x29], [0xdc,0xcb,0x23,0xc6], [0x68,0xb6,0xed,0xfc], [0x63,0xb8,0xe4,0xf1], 
	[0xca,0xd7,0x31,0xdc], [0x10,0x42,0x63,0x85], [0x40,0x13,0x97,0x22], [0x20,0x84,0xc6,0x11], 
	[0x7d,0x85,0x4a,0x24], [0xf8,0xd2,0xbb,0x3d], [0x11,0xae,0xf9,0x32], [0x6d,0xc7,0x29,0xa1], 
	[0x4b,0x1d,0x9e,0x2f], [0xf3,0xdc,0xb2,0x30], [0xec,0x0d,0x86,0x52], [0xd0,0x77,0xc1,0xe3], 
	[0x6c,0x2b,0xb3,0x16], [0x99,0xa9,0x70,0xb9], [0xfa,0x11,0x94,0x48], [0x22,0x47,0xe9,0x64], 
	[0xc4,0xa8,0xfc,0x8c], [0x1a,0xa0,0xf0,0x3f], [0xd8,0x56,0x7d,0x2c], [0xef,0x22,0x33,0x90], 
	[0xc7,0x87,0x49,0x4e], [0xc1,0xd9,0x38,0xd1], [0xfe,0x8c,0xca,0xa2], [0x36,0x98,0xd4,0x0b], 
	[0xcf,0xa6,0xf5,0x81], [0x28,0xa5,0x7a,0xde], [0x26,0xda,0xb7,0x8e], [0xa4,0x3f,0xad,0xbf], 
	[0xe4,0x2c,0x3a,0x9d], [0x0d,0x50,0x78,0x92], [0x9b,0x6a,0x5f,0xcc], [0x62,0x54,0x7e,0x46], 
	[0xc2,0xf6,0x8d,0x13], [0xe8,0x90,0xd8,0xb8], [0x5e,0x2e,0x39,0xf7], [0xf5,0x82,0xc3,0xaf], 
	[0xbe,0x9f,0x5d,0x80], [0x7c,0x69,0xd0,0x93], [0xa9,0x6f,0xd5,0x2d], [0xb3,0xcf,0x25,0x12], 
	[0x3b,0xc8,0xac,0x99], [0xa7,0x10,0x18,0x7d], [0x6e,0xe8,0x9c,0x63], [0x7b,0xdb,0x3b,0xbb], 
	[0x09,0xcd,0x26,0x78], [0xf4,0x6e,0x59,0x18], [0x01,0xec,0x9a,0xb7], [0xa8,0x83,0x4f,0x9a], 
	[0x65,0xe6,0x95,0x6e], [0x7e,0xaa,0xff,0xe6], [0x08,0x21,0xbc,0xcf], [0xe6,0xef,0x15,0xe8], 
	[0xd9,0xba,0xe7,0x9b], [0xce,0x4a,0x6f,0x36], [0xd4,0xea,0x9f,0x09], [0xd6,0x29,0xb0,0x7c], 
	[0xaf,0x31,0xa4,0xb2], [0x31,0x2a,0x3f,0x23], [0x30,0xc6,0xa5,0x94], [0xc0,0x35,0xa2,0x66], 
	[0x37,0x74,0x4e,0xbc], [0xa6,0xfc,0x82,0xca], [0xb0,0xe0,0x90,0xd0], [0x15,0x33,0xa7,0xd8], 
	[0x4a,0xf1,0x04,0x98], [0xf7,0x41,0xec,0xda], [0x0e,0x7f,0xcd,0x50], [0x2f,0x17,0x91,0xf6], 
	[0x8d,0x76,0x4d,0xd6], [0x4d,0x43,0xef,0xb0], [0x54,0xcc,0xaa,0x4d], [0xdf,0xe4,0x96,0x04], 
	[0xe3,0x9e,0xd1,0xb5], [0x1b,0x4c,0x6a,0x88], [0xb8,0xc1,0x2c,0x1f], [0x7f,0x46,0x65,0x51], 
	[0x04,0x9d,0x5e,0xea], [0x5d,0x01,0x8c,0x35], [0x73,0xfa,0x87,0x74], [0x2e,0xfb,0x0b,0x41], 
	[0x5a,0xb3,0x67,0x1d], [0x52,0x92,0xdb,0xd2], [0x33,0xe9,0x10,0x56], [0x13,0x6d,0xd6,0x47], 
	[0x8c,0x9a,0xd7,0x61], [0x7a,0x37,0xa1,0x0c], [0x8e,0x59,0xf8,0x14], [0x89,0xeb,0x13,0x3c], 
	[0xee,0xce,0xa9,0x27], [0x35,0xb7,0x61,0xc9], [0xed,0xe1,0x1c,0xe5], [0x3c,0x7a,0x47,0xb1], 
	[0x59,0x9c,0xd2,0xdf], [0x3f,0x55,0xf2,0x73], [0x79,0x18,0x14,0xce], [0xbf,0x73,0xc7,0x37], 
	[0xea,0x53,0xf7,0xcd], [0x5b,0x5f,0xfd,0xaa], [0x14,0xdf,0x3d,0x6f], [0x86,0x78,0x44,0xdb], 
	[0x81,0xca,0xaf,0xf3], [0x3e,0xb9,0x68,0xc4], [0x2c,0x38,0x24,0x34], [0x5f,0xc2,0xa3,0x40], 
	[0x72,0x16,0x1d,0xc3], [0x0c,0xbc,0xe2,0x25], [0x8b,0x28,0x3c,0x49], [0x41,0xff,0x0d,0x95], 
	[0x71,0x39,0xa8,0x01], [0xde,0x08,0x0c,0xb3], [0x9c,0xd8,0xb4,0xe4], [0x90,0x64,0x56,0xc1], 
	[0x61,0x7b,0xcb,0x84], [0x70,0xd5,0x32,0xb6], [0x74,0x48,0x6c,0x5c], [0x42,0xd0,0xb8,0x57]
);

my @T7 = (
	[0xa7,0x50,0x51,0xf4], [0x65,0x53,0x7e,0x41], [0xa4,0xc3,0x1a,0x17], [0x5e,0x96,0x3a,0x27], 
	[0x6b,0xcb,0x3b,0xab], [0x45,0xf1,0x1f,0x9d], [0x58,0xab,0xac,0xfa], [0x03,0x93,0x4b,0xe3], 
	[0xfa,0x55,0x20,0x30], [0x6d,0xf6,0xad,0x76], [0x76,0x91,0x88,0xcc], [0x4c,0x25,0xf5,0x02], 
	[0xd7,0xfc,0x4f,0xe5], [0xcb,0xd7,0xc5,0x2a], [0x44,0x80,0x26,0x35], [0xa3,0x8f,0xb5,0x62], 
	[0x5a,0x49,0xde,0xb1], [0x1b,0x67,0x25,0xba], [0x0e,0x98,0x45,0xea], [0xc0,0xe1,0x5d,0xfe], 
	[0x75,0x02,0xc3,0x2f], [0xf0,0x12,0x81,0x4c], [0x97,0xa3,0x8d,0x46], [0xf9,0xc6,0x6b,0xd3], 
	[0x5f,0xe7,0x03,0x8f], [0x9c,0x95,0x15,0x92], [0x7a,0xeb,0xbf,0x6d], [0x59,0xda,0x95,0x52], 
	[0x83,0x2d,0xd4,0xbe], [0x21,0xd3,0x58,0x74], [0x69,0x29,0x49,0xe0], [0xc8,0x44,0x8e,0xc9], 
	[0x89,0x6a,0x75,0xc2], [0x79,0x78,0xf4,0x8e], [0x3e,0x6b,0x99,0x58], [0x71,0xdd,0x27,0xb9], 
	[0x4f,0xb6,0xbe,0xe1], [0xad,0x17,0xf0,0x88], [0xac,0x66,0xc9,0x20], [0x3a,0xb4,0x7d,0xce], 
	[0x4a,0x18,0x63,0xdf], [0x31,0x82,0xe5,0x1a], [0x33,0x60,0x97,0x51], [0x7f,0x45,0x62,0x53], 
	[0x77,0xe0,0xb1,0x64], [0xae,0x84,0xbb,0x6b], [0xa0,0x1c,0xfe,0x81], [0x2b,0x94,0xf9,0x08], 
	[0x68,0x58,0x70,0x48], [0xfd,0x19,0x8f,0x45], [0x6c,0x87,0x94,0xde], [0xf8,0xb7,0x52,0x7b], 
	[0xd3,0x23,0xab,0x73], [0x02,0xe2,0x72,0x4b], [0x8f,0x57,0xe3,0x1f], [0xab,0x2a,0x66,0x55], 
	[0x28,0x07,0xb2,0xeb], [0xc2,0x03,0x2f,0xb5], [0x7b,0x9a,0x86,0xc5], [0x08,0xa5,0xd3,0x37], 
	[0x87,0xf2,0x30,0x28], [0xa5,0xb2,0x23,0xbf], [0x6a,0xba,0x02,0x03], [0x82,0x5c,0xed,0x16], 
	[0x1c,0x2b,0x8a,0xcf], [0xb4,0x92,0xa7,0x79], [0xf2,0xf0,0xf3,0x07], [0xe2,0xa1,0x4e,0x69], 
	[0xf4,0xcd,0x65,0xda], [0xbe,0xd5,0x06,0x05], [0x62,0x1f,0xd1,0x34], [0xfe,0x8a,0xc4,0xa6], 
	[0x53,0x9d,0x34,0x2e], [0x55,0xa0,0xa2,0xf3], [0xe1,0x32,0x05,0x8a], [0xeb,0x75,0xa4,0xf6], 
	[0xec,0x39,0x0b,0x83], [0xef,0xaa,0x40,0x60], [0x9f,0x06,0x5e,0x71], [0x10,0x51,0xbd,0x6e], 
	[0x8a,0xf9,0x3e,0x21], [0x06,0x3d,0x96,0xdd], [0x05,0xae,0xdd,0x3e], [0xbd,0x46,0x4d,0xe6], 
	[0x8d,0xb5,0x91,0x54], [0x5d,0x05,0x71,0xc4], [0xd4,0x6f,0x04,0x06], [0x15,0xff,0x60,0x50], 
	[0xfb,0x24,0x19,0x98], [0xe9,0x97,0xd6,0xbd], [0x43,0xcc,0x89,0x40], [0x9e,0x77,0x67,0xd9], 
	[0x42,0xbd,0xb0,0xe8], [0x8b,0x88,0x07,0x89], [0x5b,0x38,0xe7,0x19], [0xee,0xdb,0x79,0xc8], 
	[0x0a,0x47,0xa1,0x7c], [0x0f,0xe9,0x7c,0x42], [0x1e,0xc9,0xf8,0x84], [0x00,0x00,0x00,0x00], 
	[0x86,0x83,0x09,0x80], [0xed,0x48,0x32,0x2b], [0x70,0xac,0x1e,0x11], [0x72,0x4e,0x6c,0x5a], 
	[0xff,0xfb,0xfd,0x0e], [0x38,0x56,0x0f,0x85], [0xd5,0x1e,0x3d,0xae], [0x39,0x27,0x36,0x2d], 
	[0xd9,0x64,0x0a,0x0f], [0xa6,0x21,0x68,0x5c], [0x54,0xd1,0x9b,0x5b], [0x2e,0x3a,0x24,0x36], 
	[0x67,0xb1,0x0c,0x0a], [0xe7,0x0f,0x93,0x57], [0x96,0xd2,0xb4,0xee], [0x91,0x9e,0x1b,0x9b], 
	[0xc5,0x4f,0x80,0xc0], [0x20,0xa2,0x61,0xdc], [0x4b,0x69,0x5a,0x77], [0x1a,0x16,0x1c,0x12], 
	[0xba,0x0a,0xe2,0x93], [0x2a,0xe5,0xc0,0xa0], [0xe0,0x43,0x3c,0x22], [0x17,0x1d,0x12,0x1b], 
	[0x0d,0x0b,0x0e,0x09], [0xc7,0xad,0xf2,0x8b], [0xa8,0xb9,0x2d,0xb6], [0xa9,0xc8,0x14,0x1e], 
	[0x19,0x85,0x57,0xf1], [0x07,0x4c,0xaf,0x75], [0xdd,0xbb,0xee,0x99], [0x60,0xfd,0xa3,0x7f], 
	[0x26,0x9f,0xf7,0x01], [0xf5,0xbc,0x5c,0x72], [0x3b,0xc5,0x44,0x66], [0x7e,0x34,0x5b,0xfb], 
	[0x29,0x76,0x8b,0x43], [0xc6,0xdc,0xcb,0x23], [0xfc,0x68,0xb6,0xed], [0xf1,0x63,0xb8,0xe4], 
	[0xdc,0xca,0xd7,0x31], [0x85,0x10,0x42,0x63], [0x22,0x40,0x13,0x97], [0x11,0x20,0x84,0xc6], 
	[0x24,0x7d,0x85,0x4a], [0x3d,0xf8,0xd2,0xbb], [0x32,0x11,0xae,0xf9], [0xa1,0x6d,0xc7,0x29], 
	[0x2f,0x4b,0x1d,0x9e], [0x30,0xf3,0xdc,0xb2], [0x52,0xec,0x0d,0x86], [0xe3,0xd0,0x77,0xc1], 
	[0x16,0x6c,0x2b,0xb3], [0xb9,0x99,0xa9,0x70], [0x48,0xfa,0x11,0x94], [0x64,0x22,0x47,0xe9], 
	[0x8c,0xc4,0xa8,0xfc], [0x3f,0x1a,0xa0,0xf0], [0x2c,0xd8,0x56,0x7d], [0x90,0xef,0x22,0x33], 
	[0x4e,0xc7,0x87,0x49], [0xd1,0xc1,0xd9,0x38], [0xa2,0xfe,0x8c,0xca], [0x0b,0x36,0x98,0xd4], 
	[0x81,0xcf,0xa6,0xf5], [0xde,0x28,0xa5,0x7a], [0x8e,0x26,0xda,0xb7], [0xbf,0xa4,0x3f,0xad], 
	[0x9d,0xe4,0x2c,0x3a], [0x92,0x0d,0x50,0x78], [0xcc,0x9b,0x6a,0x5f], [0x46,0x62,0x54,0x7e], 
	[0x13,0xc2,0xf6,0x8d], [0xb8,0xe8,0x90,0xd8], [0xf7,0x5e,0x2e,0x39], [0xaf,0xf5,0x82,0xc3], 
	[0x80,0xbe,0x9f,0x5d], [0x93,0x7c,0x69,0xd0], [0x2d,0xa9,0x6f,0xd5], [0x12,0xb3,0xcf,0x25], 
	[0x99,0x3b,0xc8,0xac], [0x7d,0xa7,0x10,0x18], [0x63,0x6e,0xe8,0x9c], [0xbb,0x7b,0xdb,0x3b], 
	[0x78,0x09,0xcd,0x26], [0x18,0xf4,0x6e,0x59], [0xb7,0x01,0xec,0x9a], [0x9a,0xa8,0x83,0x4f], 
	[0x6e,0x65,0xe6,0x95], [0xe6,0x7e,0xaa,0xff], [0xcf,0x08,0x21,0xbc], [0xe8,0xe6,0xef,0x15], 
	[0x9b,0xd9,0xba,0xe7], [0x36,0xce,0x4a,0x6f], [0x09,0xd4,0xea,0x9f], [0x7c,0xd6,0x29,0xb0], 
	[0xb2,0xaf,0x31,0xa4], [0x23,0x31,0x2a,0x3f], [0x94,0x30,0xc6,0xa5], [0x66,0xc0,0x35,0xa2], 
	[0xbc,0x37,0x74,0x4e], [0xca,0xa6,0xfc,0x82], [0xd0,0xb0,0xe0,0x90], [0xd8,0x15,0x33,0xa7], 
	[0x98,0x4a,0xf1,0x04], [0xda,0xf7,0x41,0xec], [0x50,0x0e,0x7f,0xcd], [0xf6,0x2f,0x17,0x91], 
	[0xd6,0x8d,0x76,0x4d], [0xb0,0x4d,0x43,0xef], [0x4d,0x54,0xcc,0xaa], [0x04,0xdf,0xe4,0x96], 
	[0xb5,0xe3,0x9e,0xd1], [0x88,0x1b,0x4c,0x6a], [0x1f,0xb8,0xc1,0x2c], [0x51,0x7f,0x46,0x65], 
	[0xea,0x04,0x9d,0x5e], [0x35,0x5d,0x01,0x8c], [0x74,0x73,0xfa,0x87], [0x41,0x2e,0xfb,0x0b], 
	[0x1d,0x5a,0xb3,0x67], [0xd2,0x52,0x92,0xdb], [0x56,0x33,0xe9,0x10], [0x47,0x13,0x6d,0xd6], 
	[0x61,0x8c,0x9a,0xd7], [0x0c,0x7a,0x37,0xa1], [0x14,0x8e,0x59,0xf8], [0x3c,0x89,0xeb,0x13], 
	[0x27,0xee,0xce,0xa9], [0xc9,0x35,0xb7,0x61], [0xe5,0xed,0xe1,0x1c], [0xb1,0x3c,0x7a,0x47], 
	[0xdf,0x59,0x9c,0xd2], [0x73,0x3f,0x55,0xf2], [0xce,0x79,0x18,0x14], [0x37,0xbf,0x73,0xc7], 
	[0xcd,0xea,0x53,0xf7], [0xaa,0x5b,0x5f,0xfd], [0x6f,0x14,0xdf,0x3d], [0xdb,0x86,0x78,0x44], 
	[0xf3,0x81,0xca,0xaf], [0xc4,0x3e,0xb9,0x68], [0x34,0x2c,0x38,0x24], [0x40,0x5f,0xc2,0xa3], 
	[0xc3,0x72,0x16,0x1d], [0x25,0x0c,0xbc,0xe2], [0x49,0x8b,0x28,0x3c], [0x95,0x41,0xff,0x0d], 
	[0x01,0x71,0x39,0xa8], [0xb3,0xde,0x08,0x0c], [0xe4,0x9c,0xd8,0xb4], [0xc1,0x90,0x64,0x56], 
	[0x84,0x61,0x7b,0xcb], [0xb6,0x70,0xd5,0x32], [0x5c,0x74,0x48,0x6c], [0x57,0x42,0xd0,0xb8]
);

my @T8 = (
	[0xf4,0xa7,0x50,0x51], [0x41,0x65,0x53,0x7e], [0x17,0xa4,0xc3,0x1a], [0x27,0x5e,0x96,0x3a], 
	[0xab,0x6b,0xcb,0x3b], [0x9d,0x45,0xf1,0x1f], [0xfa,0x58,0xab,0xac], [0xe3,0x03,0x93,0x4b], 
	[0x30,0xfa,0x55,0x20], [0x76,0x6d,0xf6,0xad], [0xcc,0x76,0x91,0x88], [0x02,0x4c,0x25,0xf5], 
	[0xe5,0xd7,0xfc,0x4f], [0x2a,0xcb,0xd7,0xc5], [0x35,0x44,0x80,0x26], [0x62,0xa3,0x8f,0xb5], 
	[0xb1,0x5a,0x49,0xde], [0xba,0x1b,0x67,0x25], [0xea,0x0e,0x98,0x45], [0xfe,0xc0,0xe1,0x5d], 
	[0x2f,0x75,0x02,0xc3], [0x4c,0xf0,0x12,0x81], [0x46,0x97,0xa3,0x8d], [0xd3,0xf9,0xc6,0x6b], 
	[0x8f,0x5f,0xe7,0x03], [0x92,0x9c,0x95,0x15], [0x6d,0x7a,0xeb,0xbf], [0x52,0x59,0xda,0x95], 
	[0xbe,0x83,0x2d,0xd4], [0x74,0x21,0xd3,0x58], [0xe0,0x69,0x29,0x49], [0xc9,0xc8,0x44,0x8e], 
	[0xc2,0x89,0x6a,0x75], [0x8e,0x79,0x78,0xf4], [0x58,0x3e,0x6b,0x99], [0xb9,0x71,0xdd,0x27], 
	[0xe1,0x4f,0xb6,0xbe], [0x88,0xad,0x17,0xf0], [0x20,0xac,0x66,0xc9], [0xce,0x3a,0xb4,0x7d], 
	[0xdf,0x4a,0x18,0x63], [0x1a,0x31,0x82,0xe5], [0x51,0x33,0x60,0x97], [0x53,0x7f,0x45,0x62], 
	[0x64,0x77,0xe0,0xb1], [0x6b,0xae,0x84,0xbb], [0x81,0xa0,0x1c,0xfe], [0x08,0x2b,0x94,0xf9], 
	[0x48,0x68,0x58,0x70], [0x45,0xfd,0x19,0x8f], [0xde,0x6c,0x87,0x94], [0x7b,0xf8,0xb7,0x52], 
	[0x73,0xd3,0x23,0xab], [0x4b,0x02,0xe2,0x72], [0x1f,0x8f,0x57,0xe3], [0x55,0xab,0x2a,0x66], 
	[0xeb,0x28,0x07,0xb2], [0xb5,0xc2,0x03,0x2f], [0xc5,0x7b,0x9a,0x86], [0x37,0x08,0xa5,0xd3], 
	[0x28,0x87,0xf2,0x30], [0xbf,0xa5,0xb2,0x23], [0x03,0x6a,0xba,0x02], [0x16,0x82,0x5c,0xed], 
	[0xcf,0x1c,0x2b,0x8a], [0x79,0xb4,0x92,0xa7], [0x07,0xf2,0xf0,0xf3], [0x69,0xe2,0xa1,0x4e], 
	[0xda,0xf4,0xcd,0x65], [0x05,0xbe,0xd5,0x06], [0x34,0x62,0x1f,0xd1], [0xa6,0xfe,0x8a,0xc4], 
	[0x2e,0x53,0x9d,0x34], [0xf3,0x55,0xa0,0xa2], [0x8a,0xe1,0x32,0x05], [0xf6,0xeb,0x75,0xa4], 
	[0x83,0xec,0x39,0x0b], [0x60,0xef,0xaa,0x40], [0x71,0x9f,0x06,0x5e], [0x6e,0x10,0x51,0xbd], 
	[0x21,0x8a,0xf9,0x3e], [0xdd,0x06,0x3d,0x96], [0x3e,0x05,0xae,0xdd], [0xe6,0xbd,0x46,0x4d], 
	[0x54,0x8d,0xb5,0x91], [0xc4,0x5d,0x05,0x71], [0x06,0xd4,0x6f,0x04], [0x50,0x15,0xff,0x60], 
	[0x98,0xfb,0x24,0x19], [0xbd,0xe9,0x97,0xd6], [0x40,0x43,0xcc,0x89], [0xd9,0x9e,0x77,0x67], 
	[0xe8,0x42,0xbd,0xb0], [0x89,0x8b,0x88,0x07], [0x19,0x5b,0x38,0xe7], [0xc8,0xee,0xdb,0x79], 
	[0x7c,0x0a,0x47,0xa1], [0x42,0x0f,0xe9,0x7c], [0x84,0x1e,0xc9,0xf8], [0x00,0x00,0x00,0x00], 
	[0x80,0x86,0x83,0x09], [0x2b,0xed,0x48,0x32], [0x11,0x70,0xac,0x1e], [0x5a,0x72,0x4e,0x6c], 
	[0x0e,0xff,0xfb,0xfd], [0x85,0x38,0x56,0x0f], [0xae,0xd5,0x1e,0x3d], [0x2d,0x39,0x27,0x36], 
	[0x0f,0xd9,0x64,0x0a], [0x5c,0xa6,0x21,0x68], [0x5b,0x54,0xd1,0x9b], [0x36,0x2e,0x3a,0x24], 
	[0x0a,0x67,0xb1,0x0c], [0x57,0xe7,0x0f,0x93], [0xee,0x96,0xd2,0xb4], [0x9b,0x91,0x9e,0x1b], 
	[0xc0,0xc5,0x4f,0x80], [0xdc,0x20,0xa2,0x61], [0x77,0x4b,0x69,0x5a], [0x12,0x1a,0x16,0x1c], 
	[0x93,0xba,0x0a,0xe2], [0xa0,0x2a,0xe5,0xc0], [0x22,0xe0,0x43,0x3c], [0x1b,0x17,0x1d,0x12], 
	[0x09,0x0d,0x0b,0x0e], [0x8b,0xc7,0xad,0xf2], [0xb6,0xa8,0xb9,0x2d], [0x1e,0xa9,0xc8,0x14], 
	[0xf1,0x19,0x85,0x57], [0x75,0x07,0x4c,0xaf], [0x99,0xdd,0xbb,0xee], [0x7f,0x60,0xfd,0xa3], 
	[0x01,0x26,0x9f,0xf7], [0x72,0xf5,0xbc,0x5c], [0x66,0x3b,0xc5,0x44], [0xfb,0x7e,0x34,0x5b], 
	[0x43,0x29,0x76,0x8b], [0x23,0xc6,0xdc,0xcb], [0xed,0xfc,0x68,0xb6], [0xe4,0xf1,0x63,0xb8], 
	[0x31,0xdc,0xca,0xd7], [0x63,0x85,0x10,0x42], [0x97,0x22,0x40,0x13], [0xc6,0x11,0x20,0x84], 
	[0x4a,0x24,0x7d,0x85], [0xbb,0x3d,0xf8,0xd2], [0xf9,0x32,0x11,0xae], [0x29,0xa1,0x6d,0xc7], 
	[0x9e,0x2f,0x4b,0x1d], [0xb2,0x30,0xf3,0xdc], [0x86,0x52,0xec,0x0d], [0xc1,0xe3,0xd0,0x77], 
	[0xb3,0x16,0x6c,0x2b], [0x70,0xb9,0x99,0xa9], [0x94,0x48,0xfa,0x11], [0xe9,0x64,0x22,0x47], 
	[0xfc,0x8c,0xc4,0xa8], [0xf0,0x3f,0x1a,0xa0], [0x7d,0x2c,0xd8,0x56], [0x33,0x90,0xef,0x22], 
	[0x49,0x4e,0xc7,0x87], [0x38,0xd1,0xc1,0xd9], [0xca,0xa2,0xfe,0x8c], [0xd4,0x0b,0x36,0x98], 
	[0xf5,0x81,0xcf,0xa6], [0x7a,0xde,0x28,0xa5], [0xb7,0x8e,0x26,0xda], [0xad,0xbf,0xa4,0x3f], 
	[0x3a,0x9d,0xe4,0x2c], [0x78,0x92,0x0d,0x50], [0x5f,0xcc,0x9b,0x6a], [0x7e,0x46,0x62,0x54], 
	[0x8d,0x13,0xc2,0xf6], [0xd8,0xb8,0xe8,0x90], [0x39,0xf7,0x5e,0x2e], [0xc3,0xaf,0xf5,0x82], 
	[0x5d,0x80,0xbe,0x9f], [0xd0,0x93,0x7c,0x69], [0xd5,0x2d,0xa9,0x6f], [0x25,0x12,0xb3,0xcf], 
	[0xac,0x99,0x3b,0xc8], [0x18,0x7d,0xa7,0x10], [0x9c,0x63,0x6e,0xe8], [0x3b,0xbb,0x7b,0xdb], 
	[0x26,0x78,0x09,0xcd], [0x59,0x18,0xf4,0x6e], [0x9a,0xb7,0x01,0xec], [0x4f,0x9a,0xa8,0x83], 
	[0x95,0x6e,0x65,0xe6], [0xff,0xe6,0x7e,0xaa], [0xbc,0xcf,0x08,0x21], [0x15,0xe8,0xe6,0xef], 
	[0xe7,0x9b,0xd9,0xba], [0x6f,0x36,0xce,0x4a], [0x9f,0x09,0xd4,0xea], [0xb0,0x7c,0xd6,0x29], 
	[0xa4,0xb2,0xaf,0x31], [0x3f,0x23,0x31,0x2a], [0xa5,0x94,0x30,0xc6], [0xa2,0x66,0xc0,0x35], 
	[0x4e,0xbc,0x37,0x74], [0x82,0xca,0xa6,0xfc], [0x90,0xd0,0xb0,0xe0], [0xa7,0xd8,0x15,0x33], 
	[0x04,0x98,0x4a,0xf1], [0xec,0xda,0xf7,0x41], [0xcd,0x50,0x0e,0x7f], [0x91,0xf6,0x2f,0x17], 
	[0x4d,0xd6,0x8d,0x76], [0xef,0xb0,0x4d,0x43], [0xaa,0x4d,0x54,0xcc], [0x96,0x04,0xdf,0xe4], 
	[0xd1,0xb5,0xe3,0x9e], [0x6a,0x88,0x1b,0x4c], [0x2c,0x1f,0xb8,0xc1], [0x65,0x51,0x7f,0x46], 
	[0x5e,0xea,0x04,0x9d], [0x8c,0x35,0x5d,0x01], [0x87,0x74,0x73,0xfa], [0x0b,0x41,0x2e,0xfb], 
	[0x67,0x1d,0x5a,0xb3], [0xdb,0xd2,0x52,0x92], [0x10,0x56,0x33,0xe9], [0xd6,0x47,0x13,0x6d], 
	[0xd7,0x61,0x8c,0x9a], [0xa1,0x0c,0x7a,0x37], [0xf8,0x14,0x8e,0x59], [0x13,0x3c,0x89,0xeb], 
	[0xa9,0x27,0xee,0xce], [0x61,0xc9,0x35,0xb7], [0x1c,0xe5,0xed,0xe1], [0x47,0xb1,0x3c,0x7a], 
	[0xd2,0xdf,0x59,0x9c], [0xf2,0x73,0x3f,0x55], [0x14,0xce,0x79,0x18], [0xc7,0x37,0xbf,0x73], 
	[0xf7,0xcd,0xea,0x53], [0xfd,0xaa,0x5b,0x5f], [0x3d,0x6f,0x14,0xdf], [0x44,0xdb,0x86,0x78], 
	[0xaf,0xf3,0x81,0xca], [0x68,0xc4,0x3e,0xb9], [0x24,0x34,0x2c,0x38], [0xa3,0x40,0x5f,0xc2], 
	[0x1d,0xc3,0x72,0x16], [0xe2,0x25,0x0c,0xbc], [0x3c,0x49,0x8b,0x28], [0x0d,0x95,0x41,0xff], 
	[0xa8,0x01,0x71,0x39], [0x0c,0xb3,0xde,0x08], [0xb4,0xe4,0x9c,0xd8], [0x56,0xc1,0x90,0x64], 
	[0xcb,0x84,0x61,0x7b], [0x32,0xb6,0x70,0xd5], [0x6c,0x5c,0x74,0x48], [0xb8,0x57,0x42,0xd0]
);

my @S5 = (
	0x52,0x09,0x6a,0xd5,
	0x30,0x36,0xa5,0x38,
	0xbf,0x40,0xa3,0x9e,
	0x81,0xf3,0xd7,0xfb,
	0x7c,0xe3,0x39,0x82,
	0x9b,0x2f,0xff,0x87,
	0x34,0x8e,0x43,0x44,
	0xc4,0xde,0xe9,0xcb,
	0x54,0x7b,0x94,0x32,
	0xa6,0xc2,0x23,0x3d,
	0xee,0x4c,0x95,0x0b,
	0x42,0xfa,0xc3,0x4e,
	0x08,0x2e,0xa1,0x66,
	0x28,0xd9,0x24,0xb2,
	0x76,0x5b,0xa2,0x49,
	0x6d,0x8b,0xd1,0x25,
	0x72,0xf8,0xf6,0x64,
	0x86,0x68,0x98,0x16,
	0xd4,0xa4,0x5c,0xcc,
	0x5d,0x65,0xb6,0x92,
	0x6c,0x70,0x48,0x50,
	0xfd,0xed,0xb9,0xda,
	0x5e,0x15,0x46,0x57,
	0xa7,0x8d,0x9d,0x84,
	0x90,0xd8,0xab,0x00,
	0x8c,0xbc,0xd3,0x0a,
	0xf7,0xe4,0x58,0x05,
	0xb8,0xb3,0x45,0x06,
	0xd0,0x2c,0x1e,0x8f,
	0xca,0x3f,0x0f,0x02,
	0xc1,0xaf,0xbd,0x03,
	0x01,0x13,0x8a,0x6b,
	0x3a,0x91,0x11,0x41,
	0x4f,0x67,0xdc,0xea,
	0x97,0xf2,0xcf,0xce,
	0xf0,0xb4,0xe6,0x73,
	0x96,0xac,0x74,0x22,
	0xe7,0xad,0x35,0x85,
	0xe2,0xf9,0x37,0xe8,
	0x1c,0x75,0xdf,0x6e,
	0x47,0xf1,0x1a,0x71,
	0x1d,0x29,0xc5,0x89,
	0x6f,0xb7,0x62,0x0e,
	0xaa,0x18,0xbe,0x1b,
	0xfc,0x56,0x3e,0x4b,
	0xc6,0xd2,0x79,0x20,
	0x9a,0xdb,0xc0,0xfe,
	0x78,0xcd,0x5a,0xf4,
	0x1f,0xdd,0xa8,0x33,
	0x88,0x07,0xc7,0x31,
	0xb1,0x12,0x10,0x59,
	0x27,0x80,0xec,0x5f,
	0x60,0x51,0x7f,0xa9,
	0x19,0xb5,0x4a,0x0d,
	0x2d,0xe5,0x7a,0x9f,
	0x93,0xc9,0x9c,0xef,
	0xa0,0xe0,0x3b,0x4d,
	0xae,0x2a,0xf5,0xb0,
	0xc8,0xeb,0xbb,0x3c,
	0x83,0x53,0x99,0x61,
	0x17,0x2b,0x04,0x7e,
	0xba,0x77,0xd6,0x26,
	0xe1,0x69,0x14,0x63,
	0x55,0x21,0x0c,0x7d
);

my @U1 = (
	[0x00,0x00,0x00,0x00], [0x0e,0x09,0x0d,0x0b], [0x1c,0x12,0x1a,0x16], [0x12,0x1b,0x17,0x1d], 
	[0x38,0x24,0x34,0x2c], [0x36,0x2d,0x39,0x27], [0x24,0x36,0x2e,0x3a], [0x2a,0x3f,0x23,0x31], 
	[0x70,0x48,0x68,0x58], [0x7e,0x41,0x65,0x53], [0x6c,0x5a,0x72,0x4e], [0x62,0x53,0x7f,0x45], 
	[0x48,0x6c,0x5c,0x74], [0x46,0x65,0x51,0x7f], [0x54,0x7e,0x46,0x62], [0x5a,0x77,0x4b,0x69], 
	[0xe0,0x90,0xd0,0xb0], [0xee,0x99,0xdd,0xbb], [0xfc,0x82,0xca,0xa6], [0xf2,0x8b,0xc7,0xad], 
	[0xd8,0xb4,0xe4,0x9c], [0xd6,0xbd,0xe9,0x97], [0xc4,0xa6,0xfe,0x8a], [0xca,0xaf,0xf3,0x81], 
	[0x90,0xd8,0xb8,0xe8], [0x9e,0xd1,0xb5,0xe3], [0x8c,0xca,0xa2,0xfe], [0x82,0xc3,0xaf,0xf5], 
	[0xa8,0xfc,0x8c,0xc4], [0xa6,0xf5,0x81,0xcf], [0xb4,0xee,0x96,0xd2], [0xba,0xe7,0x9b,0xd9], 
	[0xdb,0x3b,0xbb,0x7b], [0xd5,0x32,0xb6,0x70], [0xc7,0x29,0xa1,0x6d], [0xc9,0x20,0xac,0x66], 
	[0xe3,0x1f,0x8f,0x57], [0xed,0x16,0x82,0x5c], [0xff,0x0d,0x95,0x41], [0xf1,0x04,0x98,0x4a], 
	[0xab,0x73,0xd3,0x23], [0xa5,0x7a,0xde,0x28], [0xb7,0x61,0xc9,0x35], [0xb9,0x68,0xc4,0x3e], 
	[0x93,0x57,0xe7,0x0f], [0x9d,0x5e,0xea,0x04], [0x8f,0x45,0xfd,0x19], [0x81,0x4c,0xf0,0x12], 
	[0x3b,0xab,0x6b,0xcb], [0x35,0xa2,0x66,0xc0], [0x27,0xb9,0x71,0xdd], [0x29,0xb0,0x7c,0xd6], 
	[0x03,0x8f,0x5f,0xe7], [0x0d,0x86,0x52,0xec], [0x1f,0x9d,0x45,0xf1], [0x11,0x94,0x48,0xfa], 
	[0x4b,0xe3,0x03,0x93], [0x45,0xea,0x0e,0x98], [0x57,0xf1,0x19,0x85], [0x59,0xf8,0x14,0x8e], 
	[0x73,0xc7,0x37,0xbf], [0x7d,0xce,0x3a,0xb4], [0x6f,0xd5,0x2d,0xa9], [0x61,0xdc,0x20,0xa2], 
	[0xad,0x76,0x6d,0xf6], [0xa3,0x7f,0x60,0xfd], [0xb1,0x64,0x77,0xe0], [0xbf,0x6d,0x7a,0xeb], 
	[0x95,0x52,0x59,0xda], [0x9b,0x5b,0x54,0xd1], [0x89,0x40,0x43,0xcc], [0x87,0x49,0x4e,0xc7], 
	[0xdd,0x3e,0x05,0xae], [0xd3,0x37,0x08,0xa5], [0xc1,0x2c,0x1f,0xb8], [0xcf,0x25,0x12,0xb3], 
	[0xe5,0x1a,0x31,0x82], [0xeb,0x13,0x3c,0x89], [0xf9,0x08,0x2b,0x94], [0xf7,0x01,0x26,0x9f], 
	[0x4d,0xe6,0xbd,0x46], [0x43,0xef,0xb0,0x4d], [0x51,0xf4,0xa7,0x50], [0x5f,0xfd,0xaa,0x5b], 
	[0x75,0xc2,0x89,0x6a], [0x7b,0xcb,0x84,0x61], [0x69,0xd0,0x93,0x7c], [0x67,0xd9,0x9e,0x77], 
	[0x3d,0xae,0xd5,0x1e], [0x33,0xa7,0xd8,0x15], [0x21,0xbc,0xcf,0x08], [0x2f,0xb5,0xc2,0x03], 
	[0x05,0x8a,0xe1,0x32], [0x0b,0x83,0xec,0x39], [0x19,0x98,0xfb,0x24], [0x17,0x91,0xf6,0x2f], 
	[0x76,0x4d,0xd6,0x8d], [0x78,0x44,0xdb,0x86], [0x6a,0x5f,0xcc,0x9b], [0x64,0x56,0xc1,0x90], 
	[0x4e,0x69,0xe2,0xa1], [0x40,0x60,0xef,0xaa], [0x52,0x7b,0xf8,0xb7], [0x5c,0x72,0xf5,0xbc], 
	[0x06,0x05,0xbe,0xd5], [0x08,0x0c,0xb3,0xde], [0x1a,0x17,0xa4,0xc3], [0x14,0x1e,0xa9,0xc8], 
	[0x3e,0x21,0x8a,0xf9], [0x30,0x28,0x87,0xf2], [0x22,0x33,0x90,0xef], [0x2c,0x3a,0x9d,0xe4], 
	[0x96,0xdd,0x06,0x3d], [0x98,0xd4,0x0b,0x36], [0x8a,0xcf,0x1c,0x2b], [0x84,0xc6,0x11,0x20], 
	[0xae,0xf9,0x32,0x11], [0xa0,0xf0,0x3f,0x1a], [0xb2,0xeb,0x28,0x07], [0xbc,0xe2,0x25,0x0c], 
	[0xe6,0x95,0x6e,0x65], [0xe8,0x9c,0x63,0x6e], [0xfa,0x87,0x74,0x73], [0xf4,0x8e,0x79,0x78], 
	[0xde,0xb1,0x5a,0x49], [0xd0,0xb8,0x57,0x42], [0xc2,0xa3,0x40,0x5f], [0xcc,0xaa,0x4d,0x54], 
	[0x41,0xec,0xda,0xf7], [0x4f,0xe5,0xd7,0xfc], [0x5d,0xfe,0xc0,0xe1], [0x53,0xf7,0xcd,0xea], 
	[0x79,0xc8,0xee,0xdb], [0x77,0xc1,0xe3,0xd0], [0x65,0xda,0xf4,0xcd], [0x6b,0xd3,0xf9,0xc6], 
	[0x31,0xa4,0xb2,0xaf], [0x3f,0xad,0xbf,0xa4], [0x2d,0xb6,0xa8,0xb9], [0x23,0xbf,0xa5,0xb2], 
	[0x09,0x80,0x86,0x83], [0x07,0x89,0x8b,0x88], [0x15,0x92,0x9c,0x95], [0x1b,0x9b,0x91,0x9e], 
	[0xa1,0x7c,0x0a,0x47], [0xaf,0x75,0x07,0x4c], [0xbd,0x6e,0x10,0x51], [0xb3,0x67,0x1d,0x5a], 
	[0x99,0x58,0x3e,0x6b], [0x97,0x51,0x33,0x60], [0x85,0x4a,0x24,0x7d], [0x8b,0x43,0x29,0x76], 
	[0xd1,0x34,0x62,0x1f], [0xdf,0x3d,0x6f,0x14], [0xcd,0x26,0x78,0x09], [0xc3,0x2f,0x75,0x02], 
	[0xe9,0x10,0x56,0x33], [0xe7,0x19,0x5b,0x38], [0xf5,0x02,0x4c,0x25], [0xfb,0x0b,0x41,0x2e], 
	[0x9a,0xd7,0x61,0x8c], [0x94,0xde,0x6c,0x87], [0x86,0xc5,0x7b,0x9a], [0x88,0xcc,0x76,0x91], 
	[0xa2,0xf3,0x55,0xa0], [0xac,0xfa,0x58,0xab], [0xbe,0xe1,0x4f,0xb6], [0xb0,0xe8,0x42,0xbd], 
	[0xea,0x9f,0x09,0xd4], [0xe4,0x96,0x04,0xdf], [0xf6,0x8d,0x13,0xc2], [0xf8,0x84,0x1e,0xc9], 
	[0xd2,0xbb,0x3d,0xf8], [0xdc,0xb2,0x30,0xf3], [0xce,0xa9,0x27,0xee], [0xc0,0xa0,0x2a,0xe5], 
	[0x7a,0x47,0xb1,0x3c], [0x74,0x4e,0xbc,0x37], [0x66,0x55,0xab,0x2a], [0x68,0x5c,0xa6,0x21], 
	[0x42,0x63,0x85,0x10], [0x4c,0x6a,0x88,0x1b], [0x5e,0x71,0x9f,0x06], [0x50,0x78,0x92,0x0d], 
	[0x0a,0x0f,0xd9,0x64], [0x04,0x06,0xd4,0x6f], [0x16,0x1d,0xc3,0x72], [0x18,0x14,0xce,0x79], 
	[0x32,0x2b,0xed,0x48], [0x3c,0x22,0xe0,0x43], [0x2e,0x39,0xf7,0x5e], [0x20,0x30,0xfa,0x55], 
	[0xec,0x9a,0xb7,0x01], [0xe2,0x93,0xba,0x0a], [0xf0,0x88,0xad,0x17], [0xfe,0x81,0xa0,0x1c], 
	[0xd4,0xbe,0x83,0x2d], [0xda,0xb7,0x8e,0x26], [0xc8,0xac,0x99,0x3b], [0xc6,0xa5,0x94,0x30], 
	[0x9c,0xd2,0xdf,0x59], [0x92,0xdb,0xd2,0x52], [0x80,0xc0,0xc5,0x4f], [0x8e,0xc9,0xc8,0x44], 
	[0xa4,0xf6,0xeb,0x75], [0xaa,0xff,0xe6,0x7e], [0xb8,0xe4,0xf1,0x63], [0xb6,0xed,0xfc,0x68], 
	[0x0c,0x0a,0x67,0xb1], [0x02,0x03,0x6a,0xba], [0x10,0x18,0x7d,0xa7], [0x1e,0x11,0x70,0xac], 
	[0x34,0x2e,0x53,0x9d], [0x3a,0x27,0x5e,0x96], [0x28,0x3c,0x49,0x8b], [0x26,0x35,0x44,0x80], 
	[0x7c,0x42,0x0f,0xe9], [0x72,0x4b,0x02,0xe2], [0x60,0x50,0x15,0xff], [0x6e,0x59,0x18,0xf4], 
	[0x44,0x66,0x3b,0xc5], [0x4a,0x6f,0x36,0xce], [0x58,0x74,0x21,0xd3], [0x56,0x7d,0x2c,0xd8], 
	[0x37,0xa1,0x0c,0x7a], [0x39,0xa8,0x01,0x71], [0x2b,0xb3,0x16,0x6c], [0x25,0xba,0x1b,0x67], 
	[0x0f,0x85,0x38,0x56], [0x01,0x8c,0x35,0x5d], [0x13,0x97,0x22,0x40], [0x1d,0x9e,0x2f,0x4b], 
	[0x47,0xe9,0x64,0x22], [0x49,0xe0,0x69,0x29], [0x5b,0xfb,0x7e,0x34], [0x55,0xf2,0x73,0x3f], 
	[0x7f,0xcd,0x50,0x0e], [0x71,0xc4,0x5d,0x05], [0x63,0xdf,0x4a,0x18], [0x6d,0xd6,0x47,0x13], 
	[0xd7,0x31,0xdc,0xca], [0xd9,0x38,0xd1,0xc1], [0xcb,0x23,0xc6,0xdc], [0xc5,0x2a,0xcb,0xd7], 
	[0xef,0x15,0xe8,0xe6], [0xe1,0x1c,0xe5,0xed], [0xf3,0x07,0xf2,0xf0], [0xfd,0x0e,0xff,0xfb], 
	[0xa7,0x79,0xb4,0x92], [0xa9,0x70,0xb9,0x99], [0xbb,0x6b,0xae,0x84], [0xb5,0x62,0xa3,0x8f], 
	[0x9f,0x5d,0x80,0xbe], [0x91,0x54,0x8d,0xb5], [0x83,0x4f,0x9a,0xa8], [0x8d,0x46,0x97,0xa3]
);

my @U2 = (
	[0x00,0x00,0x00,0x00], [0x0b,0x0e,0x09,0x0d], [0x16,0x1c,0x12,0x1a], [0x1d,0x12,0x1b,0x17], 
	[0x2c,0x38,0x24,0x34], [0x27,0x36,0x2d,0x39], [0x3a,0x24,0x36,0x2e], [0x31,0x2a,0x3f,0x23], 
	[0x58,0x70,0x48,0x68], [0x53,0x7e,0x41,0x65], [0x4e,0x6c,0x5a,0x72], [0x45,0x62,0x53,0x7f], 
	[0x74,0x48,0x6c,0x5c], [0x7f,0x46,0x65,0x51], [0x62,0x54,0x7e,0x46], [0x69,0x5a,0x77,0x4b], 
	[0xb0,0xe0,0x90,0xd0], [0xbb,0xee,0x99,0xdd], [0xa6,0xfc,0x82,0xca], [0xad,0xf2,0x8b,0xc7], 
	[0x9c,0xd8,0xb4,0xe4], [0x97,0xd6,0xbd,0xe9], [0x8a,0xc4,0xa6,0xfe], [0x81,0xca,0xaf,0xf3], 
	[0xe8,0x90,0xd8,0xb8], [0xe3,0x9e,0xd1,0xb5], [0xfe,0x8c,0xca,0xa2], [0xf5,0x82,0xc3,0xaf], 
	[0xc4,0xa8,0xfc,0x8c], [0xcf,0xa6,0xf5,0x81], [0xd2,0xb4,0xee,0x96], [0xd9,0xba,0xe7,0x9b], 
	[0x7b,0xdb,0x3b,0xbb], [0x70,0xd5,0x32,0xb6], [0x6d,0xc7,0x29,0xa1], [0x66,0xc9,0x20,0xac], 
	[0x57,0xe3,0x1f,0x8f], [0x5c,0xed,0x16,0x82], [0x41,0xff,0x0d,0x95], [0x4a,0xf1,0x04,0x98], 
	[0x23,0xab,0x73,0xd3], [0x28,0xa5,0x7a,0xde], [0x35,0xb7,0x61,0xc9], [0x3e,0xb9,0x68,0xc4], 
	[0x0f,0x93,0x57,0xe7], [0x04,0x9d,0x5e,0xea], [0x19,0x8f,0x45,0xfd], [0x12,0x81,0x4c,0xf0], 
	[0xcb,0x3b,0xab,0x6b], [0xc0,0x35,0xa2,0x66], [0xdd,0x27,0xb9,0x71], [0xd6,0x29,0xb0,0x7c], 
	[0xe7,0x03,0x8f,0x5f], [0xec,0x0d,0x86,0x52], [0xf1,0x1f,0x9d,0x45], [0xfa,0x11,0x94,0x48], 
	[0x93,0x4b,0xe3,0x03], [0x98,0x45,0xea,0x0e], [0x85,0x57,0xf1,0x19], [0x8e,0x59,0xf8,0x14], 
	[0xbf,0x73,0xc7,0x37], [0xb4,0x7d,0xce,0x3a], [0xa9,0x6f,0xd5,0x2d], [0xa2,0x61,0xdc,0x20], 
	[0xf6,0xad,0x76,0x6d], [0xfd,0xa3,0x7f,0x60], [0xe0,0xb1,0x64,0x77], [0xeb,0xbf,0x6d,0x7a], 
	[0xda,0x95,0x52,0x59], [0xd1,0x9b,0x5b,0x54], [0xcc,0x89,0x40,0x43], [0xc7,0x87,0x49,0x4e], 
	[0xae,0xdd,0x3e,0x05], [0xa5,0xd3,0x37,0x08], [0xb8,0xc1,0x2c,0x1f], [0xb3,0xcf,0x25,0x12], 
	[0x82,0xe5,0x1a,0x31], [0x89,0xeb,0x13,0x3c], [0x94,0xf9,0x08,0x2b], [0x9f,0xf7,0x01,0x26], 
	[0x46,0x4d,0xe6,0xbd], [0x4d,0x43,0xef,0xb0], [0x50,0x51,0xf4,0xa7], [0x5b,0x5f,0xfd,0xaa], 
	[0x6a,0x75,0xc2,0x89], [0x61,0x7b,0xcb,0x84], [0x7c,0x69,0xd0,0x93], [0x77,0x67,0xd9,0x9e], 
	[0x1e,0x3d,0xae,0xd5], [0x15,0x33,0xa7,0xd8], [0x08,0x21,0xbc,0xcf], [0x03,0x2f,0xb5,0xc2], 
	[0x32,0x05,0x8a,0xe1], [0x39,0x0b,0x83,0xec], [0x24,0x19,0x98,0xfb], [0x2f,0x17,0x91,0xf6], 
	[0x8d,0x76,0x4d,0xd6], [0x86,0x78,0x44,0xdb], [0x9b,0x6a,0x5f,0xcc], [0x90,0x64,0x56,0xc1], 
	[0xa1,0x4e,0x69,0xe2], [0xaa,0x40,0x60,0xef], [0xb7,0x52,0x7b,0xf8], [0xbc,0x5c,0x72,0xf5], 
	[0xd5,0x06,0x05,0xbe], [0xde,0x08,0x0c,0xb3], [0xc3,0x1a,0x17,0xa4], [0xc8,0x14,0x1e,0xa9], 
	[0xf9,0x3e,0x21,0x8a], [0xf2,0x30,0x28,0x87], [0xef,0x22,0x33,0x90], [0xe4,0x2c,0x3a,0x9d], 
	[0x3d,0x96,0xdd,0x06], [0x36,0x98,0xd4,0x0b], [0x2b,0x8a,0xcf,0x1c], [0x20,0x84,0xc6,0x11], 
	[0x11,0xae,0xf9,0x32], [0x1a,0xa0,0xf0,0x3f], [0x07,0xb2,0xeb,0x28], [0x0c,0xbc,0xe2,0x25], 
	[0x65,0xe6,0x95,0x6e], [0x6e,0xe8,0x9c,0x63], [0x73,0xfa,0x87,0x74], [0x78,0xf4,0x8e,0x79], 
	[0x49,0xde,0xb1,0x5a], [0x42,0xd0,0xb8,0x57], [0x5f,0xc2,0xa3,0x40], [0x54,0xcc,0xaa,0x4d], 
	[0xf7,0x41,0xec,0xda], [0xfc,0x4f,0xe5,0xd7], [0xe1,0x5d,0xfe,0xc0], [0xea,0x53,0xf7,0xcd], 
	[0xdb,0x79,0xc8,0xee], [0xd0,0x77,0xc1,0xe3], [0xcd,0x65,0xda,0xf4], [0xc6,0x6b,0xd3,0xf9], 
	[0xaf,0x31,0xa4,0xb2], [0xa4,0x3f,0xad,0xbf], [0xb9,0x2d,0xb6,0xa8], [0xb2,0x23,0xbf,0xa5], 
	[0x83,0x09,0x80,0x86], [0x88,0x07,0x89,0x8b], [0x95,0x15,0x92,0x9c], [0x9e,0x1b,0x9b,0x91], 
	[0x47,0xa1,0x7c,0x0a], [0x4c,0xaf,0x75,0x07], [0x51,0xbd,0x6e,0x10], [0x5a,0xb3,0x67,0x1d], 
	[0x6b,0x99,0x58,0x3e], [0x60,0x97,0x51,0x33], [0x7d,0x85,0x4a,0x24], [0x76,0x8b,0x43,0x29], 
	[0x1f,0xd1,0x34,0x62], [0x14,0xdf,0x3d,0x6f], [0x09,0xcd,0x26,0x78], [0x02,0xc3,0x2f,0x75], 
	[0x33,0xe9,0x10,0x56], [0x38,0xe7,0x19,0x5b], [0x25,0xf5,0x02,0x4c], [0x2e,0xfb,0x0b,0x41], 
	[0x8c,0x9a,0xd7,0x61], [0x87,0x94,0xde,0x6c], [0x9a,0x86,0xc5,0x7b], [0x91,0x88,0xcc,0x76], 
	[0xa0,0xa2,0xf3,0x55], [0xab,0xac,0xfa,0x58], [0xb6,0xbe,0xe1,0x4f], [0xbd,0xb0,0xe8,0x42], 
	[0xd4,0xea,0x9f,0x09], [0xdf,0xe4,0x96,0x04], [0xc2,0xf6,0x8d,0x13], [0xc9,0xf8,0x84,0x1e], 
	[0xf8,0xd2,0xbb,0x3d], [0xf3,0xdc,0xb2,0x30], [0xee,0xce,0xa9,0x27], [0xe5,0xc0,0xa0,0x2a], 
	[0x3c,0x7a,0x47,0xb1], [0x37,0x74,0x4e,0xbc], [0x2a,0x66,0x55,0xab], [0x21,0x68,0x5c,0xa6], 
	[0x10,0x42,0x63,0x85], [0x1b,0x4c,0x6a,0x88], [0x06,0x5e,0x71,0x9f], [0x0d,0x50,0x78,0x92], 
	[0x64,0x0a,0x0f,0xd9], [0x6f,0x04,0x06,0xd4], [0x72,0x16,0x1d,0xc3], [0x79,0x18,0x14,0xce], 
	[0x48,0x32,0x2b,0xed], [0x43,0x3c,0x22,0xe0], [0x5e,0x2e,0x39,0xf7], [0x55,0x20,0x30,0xfa], 
	[0x01,0xec,0x9a,0xb7], [0x0a,0xe2,0x93,0xba], [0x17,0xf0,0x88,0xad], [0x1c,0xfe,0x81,0xa0], 
	[0x2d,0xd4,0xbe,0x83], [0x26,0xda,0xb7,0x8e], [0x3b,0xc8,0xac,0x99], [0x30,0xc6,0xa5,0x94], 
	[0x59,0x9c,0xd2,0xdf], [0x52,0x92,0xdb,0xd2], [0x4f,0x80,0xc0,0xc5], [0x44,0x8e,0xc9,0xc8], 
	[0x75,0xa4,0xf6,0xeb], [0x7e,0xaa,0xff,0xe6], [0x63,0xb8,0xe4,0xf1], [0x68,0xb6,0xed,0xfc], 
	[0xb1,0x0c,0x0a,0x67], [0xba,0x02,0x03,0x6a], [0xa7,0x10,0x18,0x7d], [0xac,0x1e,0x11,0x70], 
	[0x9d,0x34,0x2e,0x53], [0x96,0x3a,0x27,0x5e], [0x8b,0x28,0x3c,0x49], [0x80,0x26,0x35,0x44], 
	[0xe9,0x7c,0x42,0x0f], [0xe2,0x72,0x4b,0x02], [0xff,0x60,0x50,0x15], [0xf4,0x6e,0x59,0x18], 
	[0xc5,0x44,0x66,0x3b], [0xce,0x4a,0x6f,0x36], [0xd3,0x58,0x74,0x21], [0xd8,0x56,0x7d,0x2c], 
	[0x7a,0x37,0xa1,0x0c], [0x71,0x39,0xa8,0x01], [0x6c,0x2b,0xb3,0x16], [0x67,0x25,0xba,0x1b], 
	[0x56,0x0f,0x85,0x38], [0x5d,0x01,0x8c,0x35], [0x40,0x13,0x97,0x22], [0x4b,0x1d,0x9e,0x2f], 
	[0x22,0x47,0xe9,0x64], [0x29,0x49,0xe0,0x69], [0x34,0x5b,0xfb,0x7e], [0x3f,0x55,0xf2,0x73], 
	[0x0e,0x7f,0xcd,0x50], [0x05,0x71,0xc4,0x5d], [0x18,0x63,0xdf,0x4a], [0x13,0x6d,0xd6,0x47], 
	[0xca,0xd7,0x31,0xdc], [0xc1,0xd9,0x38,0xd1], [0xdc,0xcb,0x23,0xc6], [0xd7,0xc5,0x2a,0xcb], 
	[0xe6,0xef,0x15,0xe8], [0xed,0xe1,0x1c,0xe5], [0xf0,0xf3,0x07,0xf2], [0xfb,0xfd,0x0e,0xff], 
	[0x92,0xa7,0x79,0xb4], [0x99,0xa9,0x70,0xb9], [0x84,0xbb,0x6b,0xae], [0x8f,0xb5,0x62,0xa3], 
	[0xbe,0x9f,0x5d,0x80], [0xb5,0x91,0x54,0x8d], [0xa8,0x83,0x4f,0x9a], [0xa3,0x8d,0x46,0x97]
);

my @U3 = (
	[0x00,0x00,0x00,0x00], [0x0d,0x0b,0x0e,0x09], [0x1a,0x16,0x1c,0x12], [0x17,0x1d,0x12,0x1b], 
	[0x34,0x2c,0x38,0x24], [0x39,0x27,0x36,0x2d], [0x2e,0x3a,0x24,0x36], [0x23,0x31,0x2a,0x3f], 
	[0x68,0x58,0x70,0x48], [0x65,0x53,0x7e,0x41], [0x72,0x4e,0x6c,0x5a], [0x7f,0x45,0x62,0x53], 
	[0x5c,0x74,0x48,0x6c], [0x51,0x7f,0x46,0x65], [0x46,0x62,0x54,0x7e], [0x4b,0x69,0x5a,0x77], 
	[0xd0,0xb0,0xe0,0x90], [0xdd,0xbb,0xee,0x99], [0xca,0xa6,0xfc,0x82], [0xc7,0xad,0xf2,0x8b], 
	[0xe4,0x9c,0xd8,0xb4], [0xe9,0x97,0xd6,0xbd], [0xfe,0x8a,0xc4,0xa6], [0xf3,0x81,0xca,0xaf], 
	[0xb8,0xe8,0x90,0xd8], [0xb5,0xe3,0x9e,0xd1], [0xa2,0xfe,0x8c,0xca], [0xaf,0xf5,0x82,0xc3], 
	[0x8c,0xc4,0xa8,0xfc], [0x81,0xcf,0xa6,0xf5], [0x96,0xd2,0xb4,0xee], [0x9b,0xd9,0xba,0xe7], 
	[0xbb,0x7b,0xdb,0x3b], [0xb6,0x70,0xd5,0x32], [0xa1,0x6d,0xc7,0x29], [0xac,0x66,0xc9,0x20], 
	[0x8f,0x57,0xe3,0x1f], [0x82,0x5c,0xed,0x16], [0x95,0x41,0xff,0x0d], [0x98,0x4a,0xf1,0x04], 
	[0xd3,0x23,0xab,0x73], [0xde,0x28,0xa5,0x7a], [0xc9,0x35,0xb7,0x61], [0xc4,0x3e,0xb9,0x68], 
	[0xe7,0x0f,0x93,0x57], [0xea,0x04,0x9d,0x5e], [0xfd,0x19,0x8f,0x45], [0xf0,0x12,0x81,0x4c], 
	[0x6b,0xcb,0x3b,0xab], [0x66,0xc0,0x35,0xa2], [0x71,0xdd,0x27,0xb9], [0x7c,0xd6,0x29,0xb0], 
	[0x5f,0xe7,0x03,0x8f], [0x52,0xec,0x0d,0x86], [0x45,0xf1,0x1f,0x9d], [0x48,0xfa,0x11,0x94], 
	[0x03,0x93,0x4b,0xe3], [0x0e,0x98,0x45,0xea], [0x19,0x85,0x57,0xf1], [0x14,0x8e,0x59,0xf8], 
	[0x37,0xbf,0x73,0xc7], [0x3a,0xb4,0x7d,0xce], [0x2d,0xa9,0x6f,0xd5], [0x20,0xa2,0x61,0xdc], 
	[0x6d,0xf6,0xad,0x76], [0x60,0xfd,0xa3,0x7f], [0x77,0xe0,0xb1,0x64], [0x7a,0xeb,0xbf,0x6d], 
	[0x59,0xda,0x95,0x52], [0x54,0xd1,0x9b,0x5b], [0x43,0xcc,0x89,0x40], [0x4e,0xc7,0x87,0x49], 
	[0x05,0xae,0xdd,0x3e], [0x08,0xa5,0xd3,0x37], [0x1f,0xb8,0xc1,0x2c], [0x12,0xb3,0xcf,0x25], 
	[0x31,0x82,0xe5,0x1a], [0x3c,0x89,0xeb,0x13], [0x2b,0x94,0xf9,0x08], [0x26,0x9f,0xf7,0x01], 
	[0xbd,0x46,0x4d,0xe6], [0xb0,0x4d,0x43,0xef], [0xa7,0x50,0x51,0xf4], [0xaa,0x5b,0x5f,0xfd], 
	[0x89,0x6a,0x75,0xc2], [0x84,0x61,0x7b,0xcb], [0x93,0x7c,0x69,0xd0], [0x9e,0x77,0x67,0xd9], 
	[0xd5,0x1e,0x3d,0xae], [0xd8,0x15,0x33,0xa7], [0xcf,0x08,0x21,0xbc], [0xc2,0x03,0x2f,0xb5], 
	[0xe1,0x32,0x05,0x8a], [0xec,0x39,0x0b,0x83], [0xfb,0x24,0x19,0x98], [0xf6,0x2f,0x17,0x91], 
	[0xd6,0x8d,0x76,0x4d], [0xdb,0x86,0x78,0x44], [0xcc,0x9b,0x6a,0x5f], [0xc1,0x90,0x64,0x56], 
	[0xe2,0xa1,0x4e,0x69], [0xef,0xaa,0x40,0x60], [0xf8,0xb7,0x52,0x7b], [0xf5,0xbc,0x5c,0x72], 
	[0xbe,0xd5,0x06,0x05], [0xb3,0xde,0x08,0x0c], [0xa4,0xc3,0x1a,0x17], [0xa9,0xc8,0x14,0x1e], 
	[0x8a,0xf9,0x3e,0x21], [0x87,0xf2,0x30,0x28], [0x90,0xef,0x22,0x33], [0x9d,0xe4,0x2c,0x3a], 
	[0x06,0x3d,0x96,0xdd], [0x0b,0x36,0x98,0xd4], [0x1c,0x2b,0x8a,0xcf], [0x11,0x20,0x84,0xc6], 
	[0x32,0x11,0xae,0xf9], [0x3f,0x1a,0xa0,0xf0], [0x28,0x07,0xb2,0xeb], [0x25,0x0c,0xbc,0xe2], 
	[0x6e,0x65,0xe6,0x95], [0x63,0x6e,0xe8,0x9c], [0x74,0x73,0xfa,0x87], [0x79,0x78,0xf4,0x8e], 
	[0x5a,0x49,0xde,0xb1], [0x57,0x42,0xd0,0xb8], [0x40,0x5f,0xc2,0xa3], [0x4d,0x54,0xcc,0xaa], 
	[0xda,0xf7,0x41,0xec], [0xd7,0xfc,0x4f,0xe5], [0xc0,0xe1,0x5d,0xfe], [0xcd,0xea,0x53,0xf7], 
	[0xee,0xdb,0x79,0xc8], [0xe3,0xd0,0x77,0xc1], [0xf4,0xcd,0x65,0xda], [0xf9,0xc6,0x6b,0xd3], 
	[0xb2,0xaf,0x31,0xa4], [0xbf,0xa4,0x3f,0xad], [0xa8,0xb9,0x2d,0xb6], [0xa5,0xb2,0x23,0xbf], 
	[0x86,0x83,0x09,0x80], [0x8b,0x88,0x07,0x89], [0x9c,0x95,0x15,0x92], [0x91,0x9e,0x1b,0x9b], 
	[0x0a,0x47,0xa1,0x7c], [0x07,0x4c,0xaf,0x75], [0x10,0x51,0xbd,0x6e], [0x1d,0x5a,0xb3,0x67], 
	[0x3e,0x6b,0x99,0x58], [0x33,0x60,0x97,0x51], [0x24,0x7d,0x85,0x4a], [0x29,0x76,0x8b,0x43], 
	[0x62,0x1f,0xd1,0x34], [0x6f,0x14,0xdf,0x3d], [0x78,0x09,0xcd,0x26], [0x75,0x02,0xc3,0x2f], 
	[0x56,0x33,0xe9,0x10], [0x5b,0x38,0xe7,0x19], [0x4c,0x25,0xf5,0x02], [0x41,0x2e,0xfb,0x0b], 
	[0x61,0x8c,0x9a,0xd7], [0x6c,0x87,0x94,0xde], [0x7b,0x9a,0x86,0xc5], [0x76,0x91,0x88,0xcc], 
	[0x55,0xa0,0xa2,0xf3], [0x58,0xab,0xac,0xfa], [0x4f,0xb6,0xbe,0xe1], [0x42,0xbd,0xb0,0xe8], 
	[0x09,0xd4,0xea,0x9f], [0x04,0xdf,0xe4,0x96], [0x13,0xc2,0xf6,0x8d], [0x1e,0xc9,0xf8,0x84], 
	[0x3d,0xf8,0xd2,0xbb], [0x30,0xf3,0xdc,0xb2], [0x27,0xee,0xce,0xa9], [0x2a,0xe5,0xc0,0xa0], 
	[0xb1,0x3c,0x7a,0x47], [0xbc,0x37,0x74,0x4e], [0xab,0x2a,0x66,0x55], [0xa6,0x21,0x68,0x5c], 
	[0x85,0x10,0x42,0x63], [0x88,0x1b,0x4c,0x6a], [0x9f,0x06,0x5e,0x71], [0x92,0x0d,0x50,0x78], 
	[0xd9,0x64,0x0a,0x0f], [0xd4,0x6f,0x04,0x06], [0xc3,0x72,0x16,0x1d], [0xce,0x79,0x18,0x14], 
	[0xed,0x48,0x32,0x2b], [0xe0,0x43,0x3c,0x22], [0xf7,0x5e,0x2e,0x39], [0xfa,0x55,0x20,0x30], 
	[0xb7,0x01,0xec,0x9a], [0xba,0x0a,0xe2,0x93], [0xad,0x17,0xf0,0x88], [0xa0,0x1c,0xfe,0x81], 
	[0x83,0x2d,0xd4,0xbe], [0x8e,0x26,0xda,0xb7], [0x99,0x3b,0xc8,0xac], [0x94,0x30,0xc6,0xa5], 
	[0xdf,0x59,0x9c,0xd2], [0xd2,0x52,0x92,0xdb], [0xc5,0x4f,0x80,0xc0], [0xc8,0x44,0x8e,0xc9], 
	[0xeb,0x75,0xa4,0xf6], [0xe6,0x7e,0xaa,0xff], [0xf1,0x63,0xb8,0xe4], [0xfc,0x68,0xb6,0xed], 
	[0x67,0xb1,0x0c,0x0a], [0x6a,0xba,0x02,0x03], [0x7d,0xa7,0x10,0x18], [0x70,0xac,0x1e,0x11], 
	[0x53,0x9d,0x34,0x2e], [0x5e,0x96,0x3a,0x27], [0x49,0x8b,0x28,0x3c], [0x44,0x80,0x26,0x35], 
	[0x0f,0xe9,0x7c,0x42], [0x02,0xe2,0x72,0x4b], [0x15,0xff,0x60,0x50], [0x18,0xf4,0x6e,0x59], 
	[0x3b,0xc5,0x44,0x66], [0x36,0xce,0x4a,0x6f], [0x21,0xd3,0x58,0x74], [0x2c,0xd8,0x56,0x7d], 
	[0x0c,0x7a,0x37,0xa1], [0x01,0x71,0x39,0xa8], [0x16,0x6c,0x2b,0xb3], [0x1b,0x67,0x25,0xba], 
	[0x38,0x56,0x0f,0x85], [0x35,0x5d,0x01,0x8c], [0x22,0x40,0x13,0x97], [0x2f,0x4b,0x1d,0x9e], 
	[0x64,0x22,0x47,0xe9], [0x69,0x29,0x49,0xe0], [0x7e,0x34,0x5b,0xfb], [0x73,0x3f,0x55,0xf2], 
	[0x50,0x0e,0x7f,0xcd], [0x5d,0x05,0x71,0xc4], [0x4a,0x18,0x63,0xdf], [0x47,0x13,0x6d,0xd6], 
	[0xdc,0xca,0xd7,0x31], [0xd1,0xc1,0xd9,0x38], [0xc6,0xdc,0xcb,0x23], [0xcb,0xd7,0xc5,0x2a], 
	[0xe8,0xe6,0xef,0x15], [0xe5,0xed,0xe1,0x1c], [0xf2,0xf0,0xf3,0x07], [0xff,0xfb,0xfd,0x0e], 
	[0xb4,0x92,0xa7,0x79], [0xb9,0x99,0xa9,0x70], [0xae,0x84,0xbb,0x6b], [0xa3,0x8f,0xb5,0x62], 
	[0x80,0xbe,0x9f,0x5d], [0x8d,0xb5,0x91,0x54], [0x9a,0xa8,0x83,0x4f], [0x97,0xa3,0x8d,0x46]
);

my @U4 = (
	[0x00,0x00,0x00,0x00], [0x09,0x0d,0x0b,0x0e], [0x12,0x1a,0x16,0x1c], [0x1b,0x17,0x1d,0x12], 
	[0x24,0x34,0x2c,0x38], [0x2d,0x39,0x27,0x36], [0x36,0x2e,0x3a,0x24], [0x3f,0x23,0x31,0x2a], 
	[0x48,0x68,0x58,0x70], [0x41,0x65,0x53,0x7e], [0x5a,0x72,0x4e,0x6c], [0x53,0x7f,0x45,0x62], 
	[0x6c,0x5c,0x74,0x48], [0x65,0x51,0x7f,0x46], [0x7e,0x46,0x62,0x54], [0x77,0x4b,0x69,0x5a], 
	[0x90,0xd0,0xb0,0xe0], [0x99,0xdd,0xbb,0xee], [0x82,0xca,0xa6,0xfc], [0x8b,0xc7,0xad,0xf2], 
	[0xb4,0xe4,0x9c,0xd8], [0xbd,0xe9,0x97,0xd6], [0xa6,0xfe,0x8a,0xc4], [0xaf,0xf3,0x81,0xca], 
	[0xd8,0xb8,0xe8,0x90], [0xd1,0xb5,0xe3,0x9e], [0xca,0xa2,0xfe,0x8c], [0xc3,0xaf,0xf5,0x82], 
	[0xfc,0x8c,0xc4,0xa8], [0xf5,0x81,0xcf,0xa6], [0xee,0x96,0xd2,0xb4], [0xe7,0x9b,0xd9,0xba], 
	[0x3b,0xbb,0x7b,0xdb], [0x32,0xb6,0x70,0xd5], [0x29,0xa1,0x6d,0xc7], [0x20,0xac,0x66,0xc9], 
	[0x1f,0x8f,0x57,0xe3], [0x16,0x82,0x5c,0xed], [0x0d,0x95,0x41,0xff], [0x04,0x98,0x4a,0xf1], 
	[0x73,0xd3,0x23,0xab], [0x7a,0xde,0x28,0xa5], [0x61,0xc9,0x35,0xb7], [0x68,0xc4,0x3e,0xb9], 
	[0x57,0xe7,0x0f,0x93], [0x5e,0xea,0x04,0x9d], [0x45,0xfd,0x19,0x8f], [0x4c,0xf0,0x12,0x81], 
	[0xab,0x6b,0xcb,0x3b], [0xa2,0x66,0xc0,0x35], [0xb9,0x71,0xdd,0x27], [0xb0,0x7c,0xd6,0x29], 
	[0x8f,0x5f,0xe7,0x03], [0x86,0x52,0xec,0x0d], [0x9d,0x45,0xf1,0x1f], [0x94,0x48,0xfa,0x11], 
	[0xe3,0x03,0x93,0x4b], [0xea,0x0e,0x98,0x45], [0xf1,0x19,0x85,0x57], [0xf8,0x14,0x8e,0x59], 
	[0xc7,0x37,0xbf,0x73], [0xce,0x3a,0xb4,0x7d], [0xd5,0x2d,0xa9,0x6f], [0xdc,0x20,0xa2,0x61], 
	[0x76,0x6d,0xf6,0xad], [0x7f,0x60,0xfd,0xa3], [0x64,0x77,0xe0,0xb1], [0x6d,0x7a,0xeb,0xbf], 
	[0x52,0x59,0xda,0x95], [0x5b,0x54,0xd1,0x9b], [0x40,0x43,0xcc,0x89], [0x49,0x4e,0xc7,0x87], 
	[0x3e,0x05,0xae,0xdd], [0x37,0x08,0xa5,0xd3], [0x2c,0x1f,0xb8,0xc1], [0x25,0x12,0xb3,0xcf], 
	[0x1a,0x31,0x82,0xe5], [0x13,0x3c,0x89,0xeb], [0x08,0x2b,0x94,0xf9], [0x01,0x26,0x9f,0xf7], 
	[0xe6,0xbd,0x46,0x4d], [0xef,0xb0,0x4d,0x43], [0xf4,0xa7,0x50,0x51], [0xfd,0xaa,0x5b,0x5f], 
	[0xc2,0x89,0x6a,0x75], [0xcb,0x84,0x61,0x7b], [0xd0,0x93,0x7c,0x69], [0xd9,0x9e,0x77,0x67], 
	[0xae,0xd5,0x1e,0x3d], [0xa7,0xd8,0x15,0x33], [0xbc,0xcf,0x08,0x21], [0xb5,0xc2,0x03,0x2f], 
	[0x8a,0xe1,0x32,0x05], [0x83,0xec,0x39,0x0b], [0x98,0xfb,0x24,0x19], [0x91,0xf6,0x2f,0x17], 
	[0x4d,0xd6,0x8d,0x76], [0x44,0xdb,0x86,0x78], [0x5f,0xcc,0x9b,0x6a], [0x56,0xc1,0x90,0x64], 
	[0x69,0xe2,0xa1,0x4e], [0x60,0xef,0xaa,0x40], [0x7b,0xf8,0xb7,0x52], [0x72,0xf5,0xbc,0x5c], 
	[0x05,0xbe,0xd5,0x06], [0x0c,0xb3,0xde,0x08], [0x17,0xa4,0xc3,0x1a], [0x1e,0xa9,0xc8,0x14], 
	[0x21,0x8a,0xf9,0x3e], [0x28,0x87,0xf2,0x30], [0x33,0x90,0xef,0x22], [0x3a,0x9d,0xe4,0x2c], 
	[0xdd,0x06,0x3d,0x96], [0xd4,0x0b,0x36,0x98], [0xcf,0x1c,0x2b,0x8a], [0xc6,0x11,0x20,0x84], 
	[0xf9,0x32,0x11,0xae], [0xf0,0x3f,0x1a,0xa0], [0xeb,0x28,0x07,0xb2], [0xe2,0x25,0x0c,0xbc], 
	[0x95,0x6e,0x65,0xe6], [0x9c,0x63,0x6e,0xe8], [0x87,0x74,0x73,0xfa], [0x8e,0x79,0x78,0xf4], 
	[0xb1,0x5a,0x49,0xde], [0xb8,0x57,0x42,0xd0], [0xa3,0x40,0x5f,0xc2], [0xaa,0x4d,0x54,0xcc], 
	[0xec,0xda,0xf7,0x41], [0xe5,0xd7,0xfc,0x4f], [0xfe,0xc0,0xe1,0x5d], [0xf7,0xcd,0xea,0x53], 
	[0xc8,0xee,0xdb,0x79], [0xc1,0xe3,0xd0,0x77], [0xda,0xf4,0xcd,0x65], [0xd3,0xf9,0xc6,0x6b], 
	[0xa4,0xb2,0xaf,0x31], [0xad,0xbf,0xa4,0x3f], [0xb6,0xa8,0xb9,0x2d], [0xbf,0xa5,0xb2,0x23], 
	[0x80,0x86,0x83,0x09], [0x89,0x8b,0x88,0x07], [0x92,0x9c,0x95,0x15], [0x9b,0x91,0x9e,0x1b], 
	[0x7c,0x0a,0x47,0xa1], [0x75,0x07,0x4c,0xaf], [0x6e,0x10,0x51,0xbd], [0x67,0x1d,0x5a,0xb3], 
	[0x58,0x3e,0x6b,0x99], [0x51,0x33,0x60,0x97], [0x4a,0x24,0x7d,0x85], [0x43,0x29,0x76,0x8b], 
	[0x34,0x62,0x1f,0xd1], [0x3d,0x6f,0x14,0xdf], [0x26,0x78,0x09,0xcd], [0x2f,0x75,0x02,0xc3], 
	[0x10,0x56,0x33,0xe9], [0x19,0x5b,0x38,0xe7], [0x02,0x4c,0x25,0xf5], [0x0b,0x41,0x2e,0xfb], 
	[0xd7,0x61,0x8c,0x9a], [0xde,0x6c,0x87,0x94], [0xc5,0x7b,0x9a,0x86], [0xcc,0x76,0x91,0x88], 
	[0xf3,0x55,0xa0,0xa2], [0xfa,0x58,0xab,0xac], [0xe1,0x4f,0xb6,0xbe], [0xe8,0x42,0xbd,0xb0], 
	[0x9f,0x09,0xd4,0xea], [0x96,0x04,0xdf,0xe4], [0x8d,0x13,0xc2,0xf6], [0x84,0x1e,0xc9,0xf8], 
	[0xbb,0x3d,0xf8,0xd2], [0xb2,0x30,0xf3,0xdc], [0xa9,0x27,0xee,0xce], [0xa0,0x2a,0xe5,0xc0], 
	[0x47,0xb1,0x3c,0x7a], [0x4e,0xbc,0x37,0x74], [0x55,0xab,0x2a,0x66], [0x5c,0xa6,0x21,0x68], 
	[0x63,0x85,0x10,0x42], [0x6a,0x88,0x1b,0x4c], [0x71,0x9f,0x06,0x5e], [0x78,0x92,0x0d,0x50], 
	[0x0f,0xd9,0x64,0x0a], [0x06,0xd4,0x6f,0x04], [0x1d,0xc3,0x72,0x16], [0x14,0xce,0x79,0x18], 
	[0x2b,0xed,0x48,0x32], [0x22,0xe0,0x43,0x3c], [0x39,0xf7,0x5e,0x2e], [0x30,0xfa,0x55,0x20], 
	[0x9a,0xb7,0x01,0xec], [0x93,0xba,0x0a,0xe2], [0x88,0xad,0x17,0xf0], [0x81,0xa0,0x1c,0xfe], 
	[0xbe,0x83,0x2d,0xd4], [0xb7,0x8e,0x26,0xda], [0xac,0x99,0x3b,0xc8], [0xa5,0x94,0x30,0xc6], 
	[0xd2,0xdf,0x59,0x9c], [0xdb,0xd2,0x52,0x92], [0xc0,0xc5,0x4f,0x80], [0xc9,0xc8,0x44,0x8e], 
	[0xf6,0xeb,0x75,0xa4], [0xff,0xe6,0x7e,0xaa], [0xe4,0xf1,0x63,0xb8], [0xed,0xfc,0x68,0xb6], 
	[0x0a,0x67,0xb1,0x0c], [0x03,0x6a,0xba,0x02], [0x18,0x7d,0xa7,0x10], [0x11,0x70,0xac,0x1e], 
	[0x2e,0x53,0x9d,0x34], [0x27,0x5e,0x96,0x3a], [0x3c,0x49,0x8b,0x28], [0x35,0x44,0x80,0x26], 
	[0x42,0x0f,0xe9,0x7c], [0x4b,0x02,0xe2,0x72], [0x50,0x15,0xff,0x60], [0x59,0x18,0xf4,0x6e], 
	[0x66,0x3b,0xc5,0x44], [0x6f,0x36,0xce,0x4a], [0x74,0x21,0xd3,0x58], [0x7d,0x2c,0xd8,0x56], 
	[0xa1,0x0c,0x7a,0x37], [0xa8,0x01,0x71,0x39], [0xb3,0x16,0x6c,0x2b], [0xba,0x1b,0x67,0x25], 
	[0x85,0x38,0x56,0x0f], [0x8c,0x35,0x5d,0x01], [0x97,0x22,0x40,0x13], [0x9e,0x2f,0x4b,0x1d], 
	[0xe9,0x64,0x22,0x47], [0xe0,0x69,0x29,0x49], [0xfb,0x7e,0x34,0x5b], [0xf2,0x73,0x3f,0x55], 
	[0xcd,0x50,0x0e,0x7f], [0xc4,0x5d,0x05,0x71], [0xdf,0x4a,0x18,0x63], [0xd6,0x47,0x13,0x6d], 
	[0x31,0xdc,0xca,0xd7], [0x38,0xd1,0xc1,0xd9], [0x23,0xc6,0xdc,0xcb], [0x2a,0xcb,0xd7,0xc5], 
	[0x15,0xe8,0xe6,0xef], [0x1c,0xe5,0xed,0xe1], [0x07,0xf2,0xf0,0xf3], [0x0e,0xff,0xfb,0xfd], 
	[0x79,0xb4,0x92,0xa7], [0x70,0xb9,0x99,0xa9], [0x6b,0xae,0x84,0xbb], [0x62,0xa3,0x8f,0xb5], 
	[0x5d,0x80,0xbe,0x9f], [0x54,0x8d,0xb5,0x91], [0x4f,0x9a,0xa8,0x83], [0x46,0x97,0xa3,0x8d]
);


# alg-ref.h
# define MAXBC				(256/32)
# define MAXKC				(256/32)
# define MAXROUNDS			14
sub MAXBC() { 8 }
sub MAXKC() { 8 }
sub MAXROUNDS() { 14 }


# alg-ref.c
use constant shifts => [
   [[0, 0], [1, 3], [2, 2], [3, 1]],   
   [[0, 0], [1, 5], [2, 4], [3, 3]],
   [[0, 0], [1, 7], [3, 5], [4, 4]]
];

#word8 mul(word8 a, word8 b) {
#   /* multiply two elements of GF(2^m)
#    * needed for MixColumn and InvMixColumn
#    */
#	if (a && b) return Alogtable[(Logtable[a] + Logtable[b])%255];
#	else return 0;
#}
sub mul($$) {
	$_[0] && $_[1] ? Algotable->[(Logtable->[$_[0]] + Logtable->[$_[1]]) % 255] : 0
}

#void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC) {
#	/* Exor corresponding text input and round key input bytes
#	 */
#	int i, j;
#	
#	for(i = 0; i < 4; i++)
#   		for(j = 0; j < BC; j++) a[i][j] ^= rk[i][j];
#}

#sub KeyAddition(@) {
#	my @a = @_[0..3];
#	my $rk = $_[4];
#	my $BC = $_[5];
#	my $i;
#	for $i (0..3) {
#		for my $j (0 .. $BC-1) {
#			$a[$i][$j] ^= $rk->[$i][$j]
#		}
#	}
#	@_[0..3] = @a; # return by reference
#}





sub KeyAddition {
  for my $j (0..($_[5]-1)) {
    $_[0][$j] ^= $_[4][0][$j];
    $_[1][$j] ^= $_[4][1][$j];
    $_[2][$j] ^= $_[4][2][$j];
    $_[3][$j] ^= $_[4][3][$j];

  }
}

#void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC) {
#	/* Row 0 remains unchanged
#	 * The other three rows are shifted a variable amount
#	 */
#	word8 tmp[MAXBC];
#	int i, j;
#	
#	for(i = 1; i < 4; i++) {
#		for(j = 0; j < BC; j++) tmp[j] = a[i][(j + shifts[SC][i][d]) % BC];
#		for(j = 0; j < BC; j++) a[i][j] = tmp[j];
#	}
#}

#sub ShiftRow(@) {
#	my @a = @_[0..3];
#	my ($d,$BC) = @_[4,5];
#	my @tmp;
#	my $i;
#	# define SC	((BC - 4) >> 1)
#	my $SC = ($BC-4)>>1;
#	for $i (1..3) {
#		my $j;
#		for $j (0..$BC-1) { $tmp[$j] = $a[$i][($j + shifts->[$SC][$i][$d]) % $BC]	}
#		for $j (0..$BC-1) { $a[$i][$j] = $tmp[$j] }
#	}
#	@_[0..3] = @a; # return by reference
#}

sub ShiftRow(@) {
	my @tmp;
	for my $i (1..3) {
		my $j;
		for $j (0..$_[5]-1) { $tmp[$j] = $_[$i][($j + shifts->[($_[5]-4)>>1][$i][$_[4]]) % $_[5]]	}
		for $j (0..$_[5]-1) { $_[$i][$j] = $tmp[$j] }
	}
}

#void Substitution(word8 a[4][MAXBC], word8 box[256], word8 BC) {
#	/* Replace every byte of the input by the byte at that place
#	 * in the nonlinear S-box
#	 */
#	int i, j;
#	
#	for(i = 0; i < 4; i++)
#		for(j = 0; j < BC; j++) a[i][j] = box[a[i][j]] ;
#}

sub Substitution (@) {
	die "Substitution" unless @_ == 261;
	my @a = @_[0..3];
	my @box = @_[4..259];
	my $BC = $_[260];
	my $i;
	for $i (0..3) {
		my $j;
		for $j (0..$BC-1) { $a[$i][$j] = $box[$a[$i][$j]] }
	}
	@_[0..3] = @a; # return by reference
}

#void MixColumn(word8 a[4][MAXBC], word8 BC) {
#        /* Mix the four bytes of every column in a linear way
#	 */
#	word8 b[4][MAXBC];
#	int i, j;
#		
#	for(j = 0; j < BC; j++)
#		for(i = 0; i < 4; i++)
#			b[i][j] = mul(2,a[i][j])
#				^ mul(3,a[(i + 1) % 4][j])
#				^ a[(i + 2) % 4][j]
#				^ a[(i + 3) % 4][j];
#	for(i = 0; i < 4; i++)
#		for(j = 0; j < BC; j++) a[i][j] = b[i][j];
#}

sub MixColumn (@) {
	my @a = @_[0..3];
	my $BC = $_[4];
	my @b;
	my ($j,$i);
	for $j (0..$BC-1) {
		for $i (0..3) {
			$b[$i][$j] = mul(2,$a[$i][$j])
				   ^ mul(3,$a[($i+1) % 4][$j])
				   ^ $a[($i+2) % 4][$j]
				   ^ $a[($i+3) % 4][$j]
		}
	}
	for $i (0..3) {
		for $j (0..$BC-1) {
			$a[$i][$j] = $b[$i][$j];
		}
	}
	@_[0..3] = @a; # return by reference
}

#void InvMixColumn(word8 a[4][MAXBC], word8 BC) {
#        /* Mix the four bytes of every column in a linear way
#	 * This is the opposite operation of Mixcolumn
#	 */
#	word8 b[4][MAXBC];
#	int i, j;
#	
#	for(j = 0; j < BC; j++)
#	for(i = 0; i < 4; i++)             
#		b[i][j] = mul(0xe,a[i][j])
#			^ mul(0xb,a[(i + 1) % 4][j])                 
#			^ mul(0xd,a[(i + 2) % 4][j])
#			^ mul(0x9,a[(i + 3) % 4][j]);                        
#	for(i = 0; i < 4; i++)
#		for(j = 0; j < BC; j++) a[i][j] = b[i][j];
#}

sub InvMixColumn (@) {
	my @a = @_[0..3];
	my $BC = $_[4];
	my @b;
	my ($i,$j);
	for $j (0..$BC-1) {
		for $i (0..3) {
			$b[$i][$j] = mul(0xe,$a[$i][$j])
				   ^ mul(0xb,$a[($i+1) % 4][$j])
				   ^ mul(0xd,$a[($i+2) % 4][$j])
				   ^ mul(0x9,$a[($i+3) % 4][$j])
		}
	}
	for $i (0..3) {
		for $j (0..$BC-1) {
			$a[$i][$j] = $b[$i][$j];
		}
	}
	@_[0..3] = @a; # return by reference
}

#int rijndaelKeySched (word8 k[4][MAXKC], int keyBits, int blockBits, word8 W[MAXROUNDS+1][4][MAXBC]) {
#	/* Calculate the necessary round keys
#	 * The number of calculations depends on keyBits and blockBits
#	 */
#	int KC, BC, ROUNDS;
#	int i, j, t, rconpointer = 0;
#	word8 tk[4][MAXKC];   

sub rijndaelKeySched (@) {
	my @k = @_[0..3];
	my $keyBits = $_[4];
	my $blockBits = $_[5];
	# my @W = @_[6..$#_]; # the rest
	my $W = $_[6];

	my @tk;
	my $rconpointer = 0;

#
#	switch (keyBits) {
#	case 128: KC = 4; break;
#	case 192: KC = 6; break;
#	case 256: KC = 8; break;
#	default : return (-1);
#	}
#
#	switch (blockBits) {
#	case 128: BC = 4; break;
#	case 192: BC = 6; break;
#	case 256: BC = 8; break;
#	default : return (-2);
#	}
#
#	switch (keyBits >= blockBits ? keyBits : blockBits) {
#	case 128: ROUNDS = 10; break;
#	case 192: ROUNDS = 12; break;
#	case 256: ROUNDS = 14; break;
#	default : return (-3); /* this cannot happen */
#	}

	my $KC = $keyBits == 128 ? 4 : $keyBits == 192 ? 6 : $keyBits == 256 ? 8 : return -1;

	my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;

	my $ROUNDS;
	{ my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
	  $ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
	}

#
#	
#	for(j = 0; j < KC; j++)
#		for(i = 0; i < 4; i++)
#			tk[i][j] = k[i][j];
#	t = 0;
#	/* copy values into round key array */
#	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
#		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
#

	my ($j,$i);
	for $j (0..$KC-1) {
		for $i (0..3) {
			$tk[$i][$j] = $k[$i][$j];
		}
	}

	my $t = 0;

	for ($j = 0; ($j <$KC) and ($t < ($ROUNDS+1)*$BC); $j++, $t++) {
		for $i (0..3) {
			$W->[$t/$BC][$i][$t % $BC] = $tk[$i][$j]
		}
	}
		
#	while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
#		/* calculate new values */
#		for(i = 0; i < 4; i++)
#			tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
#		tk[0][0] ^= rcon[rconpointer++];
#
#		if (KC != 8)
#			for(j = 1; j < KC; j++)
#				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
#		else {
#			for(j = 1; j < KC/2; j++)
#				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
#			for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
#			for(j = KC/2 + 1; j < KC; j++)
#				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
#		}

	while ($t < ($ROUNDS+1)*$BC) {
		for $i (0..3) {
			$tk[$i][0] ^= $S[$tk[($i+1) % 4][$KC-1]];
		}
		$tk[0][0] ^= $rcon[$rconpointer++];
		
		if ($KC != 8) {
			for $j (1..$KC-1) {
				for $i (0..3) {	$tk[$i][$j] ^= $tk[$i][$j-1] }
			}
		} else {
			for ($j = 1; $j < $KC/2; $j++) {
				for $i (0..3) {	$tk[$i][$j] ^= $tk[$i][$j-1] }
			}
			for $i (0..3) { $tk[$i][$KC/2] ^= $S[$tk[$i][$KC/2-1]] }
			for ($j = $KC/2+1; $j < $KC; $j++) {
				for $i (0..3) { $tk[$i][$j] ^= $tk[$i][$j-1] }
			}
		}

#		/* copy values into round key array */
#		for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
#			for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
#	}		
#
#	return 0;
#}

		for ($j=0; ($j<$KC) and ($t < ($ROUNDS+1)*$BC); $j++, $t++) {
			for $i (0..3) { $W->[$t/$BC][$i][$t % $BC] = $tk[$i][$j] }
		}
	}

	# @_[6..$#_] = @W; # return by reference
	$_[6] = $W;
	return 0;
}



#int rijndaelEncrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC])
#{
#	/* Encryption of one block. 
#	 */
#	int r, BC, ROUNDS;

sub rijndaelEncrypt (@) {
	my @a = @_[0..3];
	my $keyBits = $_[4];
	my $blockBits = $_[5];
	#my @rk = $_[6..$#_]; # rest
	my $rk = $_[6];
	
	my $r;

#
#	switch (blockBits) {
#	case 128: BC = 4; break;
#	case 192: BC = 6; break;
#	case 256: BC = 8; break;
#	default : return (-2);
#	}
#
#	switch (keyBits >= blockBits ? keyBits : blockBits) {
#	case 128: ROUNDS = 10; break;
#	case 192: ROUNDS = 12; break;
#	case 256: ROUNDS = 14; break;
#	default : return (-3); /* this cannot happen */
#	}

	my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;

	my $ROUNDS;
	{ my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
	  $ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
	}

#
#	/* begin with a key addition
#	 */
#	KeyAddition(a,rk[0],BC); 

	KeyAddition(@a,$rk->[0],$BC);

#
#       /* ROUNDS-1 ordinary rounds
#	 */
#	for(r = 1; r < ROUNDS; r++) {
#		Substitution(a,S,BC);
#		ShiftRow(a,0,BC);
#		MixColumn(a,BC);
#		KeyAddition(a,rk[r],BC);
#	}

	for $r (1..$ROUNDS-1) {
		Substitution(@a,@S,$BC);
		ShiftRow(@a,0,$BC);
		MixColumn(@a,$BC);
		KeyAddition(@a,$rk->[$r],$BC);
	}

#	
#	/* Last round is special: there is no MixColumn
#	 */
#	Substitution(a,S,BC);
#	ShiftRow(a,0,BC);
#	KeyAddition(a,rk[ROUNDS],BC);
#
#	return 0;
#}   
	
	Substitution(@a,@S,$BC);
	ShiftRow(@a,0,$BC);
	KeyAddition(@a,$rk->[$ROUNDS],$BC);

	@_[0..3] = @a;
	
	return 0;
}



#int rijndaelEncryptRound (word8 a[4][MAXBC], int keyBits, int blockBits, 
#		word8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
#/* Encrypt only a certain number of rounds.
# * Only used in the Intermediate Value Known Answer Test.
# */
#{
#	int r, BC, ROUNDS;

sub rijndaelEncryptRound (@) {
	my $rounds = pop; # last element
	
	my @a = @_[0..3];
	my $keyBits = $_[4];
	my $blockBits = $_[5];
	# my @rk = $_[6..$#_]; # rest
	my $rk = $_[6];
	
	my $r;

#
#	switch (blockBits) {
#	case 128: BC = 4; break;
#	case 192: BC = 6; break;
#	case 256: BC = 8; break;
#	default : return (-2);
#	}
#
#	switch (keyBits >= blockBits ? keyBits : blockBits) {
#	case 128: ROUNDS = 10; break;
#	case 192: ROUNDS = 12; break;
#	case 256: ROUNDS = 14; break;
#	default : return (-3); /* this cannot happen */
#	}

	my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;

	my $ROUNDS;
	{ my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
	  $ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
	}


#
#	/* make number of rounds sane */
#	if (rounds > ROUNDS) rounds = ROUNDS;

	$rounds = $ROUNDS if $rounds > $ROUNDS;

#
#	/* begin with a key addition
#	 */
#	KeyAddition(a,rk[0],BC);

	KeyAddition(@a,$rk->[0],$BC);
	
#       
#	/* at most ROUNDS-1 ordinary rounds
#	 */
#	for(r = 1; (r <= rounds) && (r < ROUNDS); r++) {
#		Substitution(a,S,BC);
#		ShiftRow(a,0,BC);
#		MixColumn(a,BC);
#		KeyAddition(a,rk[r],BC);
#	}
	for ($r = 1; $r <= $rounds and $r < $ROUNDS; $r++) {
		Substitution(@a,@S,$BC);
		ShiftRow(@a,0,$BC);
		MixColumn(@a,$BC);
		KeyAddition(@a,$rk->[$r],$BC);
	}
#	
#	/* if necessary, do the last, special, round: 
#	 */
#	if (rounds == ROUNDS) {
#		Substitution(a,S,BC);
#		ShiftRow(a,0,BC);
#		KeyAddition(a,rk[ROUNDS],BC);
#	}
	
	if ($rounds == $ROUNDS) {
		Substitution(@a,@S,$BC);
		ShiftRow(@a,0,$BC);
		KeyAddition(@a,$rk->[$ROUNDS],$BC);
	}

#
#	return 0;

	@_[0..3] = @a;
	
	return 0;
#}   

}




#int rijndaelDecrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC])
#{
#	int r, BC, ROUNDS;

sub rijndaelDecrypt (@) {
	
	my @a = @_[0..3];
	my $keyBits = $_[4];
	my $blockBits = $_[5];
	my $rk = $_[6];

	my $r;
	
#	
#	switch (blockBits) {
#	case 128: BC = 4; break;
#	case 192: BC = 6; break;
#	case 256: BC = 8; break;
#	default : return (-2);
#	}
#
#	switch (keyBits >= blockBits ? keyBits : blockBits) {
#	case 128: ROUNDS = 10; break;
#	case 192: ROUNDS = 12; break;
#	case 256: ROUNDS = 14; break;
#	default : return (-3); /* this cannot happen */
#	}

	my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;

	my $ROUNDS;
	{
		my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
		$ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
	}

#
#	/* To decrypt: apply the inverse operations of the encrypt routine,
#	 *             in opposite order
#	 * 
#	 * (KeyAddition is an involution: it 's equal to its inverse)
#	 * (the inverse of Substitution with table S is Substitution with the inverse table of S)
#	 * (the inverse of Shiftrow is Shiftrow over a suitable distance)
#	 */
#
#       /* First the special round:
#	 *   without InvMixColumn
#	 *   with extra KeyAddition
#	 */
#	KeyAddition(a,rk[ROUNDS],BC);
#	Substitution(a,Si,BC);
#	ShiftRow(a,1,BC);              

	KeyAddition(@a,$rk->[$ROUNDS],$BC);
	Substitution(@a,@Si,$BC);
	ShiftRow(@a,1,$BC);

#	
#	/* ROUNDS-1 ordinary rounds
#	 */
#	for(r = ROUNDS-1; r > 0; r--) {
#		KeyAddition(a,rk[r],BC);
#		InvMixColumn(a,BC);      
#		Substitution(a,Si,BC);
#		ShiftRow(a,1,BC);                
#	}

	for ($r = $ROUNDS-1; $r > 0; $r--) {
		KeyAddition(@a,$rk->[$r],$BC);
		InvMixColumn(@a,$BC);
		Substitution(@a,@Si,$BC);
		ShiftRow(@a,1,$BC);
	}
#	
#	/* End with the extra key addition
#	 */
#	
#	KeyAddition(a,rk[0],BC);    

	KeyAddition(@a,$rk->[0],$BC);

#
#	return 0;
#}

	@_[0..3] = @a;
	
	return 0;
}


#int rijndaelDecryptRound (word8 a[4][MAXBC], int keyBits, int blockBits, 
#	word8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
#/* Decrypt only a certain number of rounds.
# * Only used in the Intermediate Value Known Answer Test.
# * Operations rearranged such that the intermediate values
# * of decryption correspond with the intermediate values
# * of encryption.
# */
#{
#	int r, BC, ROUNDS;

sub rijndaelDecryptRound (@) {
	
	my @a = @_[0..3];
	my $keyBits = $_[4];
	my $blockBits = $_[5];
	my $rk = $_[6];
	my $rounds = $_[7];

	my $r;

#	
#	switch (blockBits) {
#	case 128: BC = 4; break;
#	case 192: BC = 6; break;
#	case 256: BC = 8; break;
#	default : return (-2);
#	}
#
#	switch (keyBits >= blockBits ? keyBits : blockBits) {
#	case 128: ROUNDS = 10; break;
#	case 192: ROUNDS = 12; break;
#	case 256: ROUNDS = 14; break;
#	default : return (-3); /* this cannot happen */
#	}
#

	my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;

	my $ROUNDS;
	{ 
		my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
		$ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
	}



#
#	/* make number of rounds sane */
#	if (rounds > ROUNDS) rounds = ROUNDS;

	$rounds = $ROUNDS if $rounds > $ROUNDS;

#
#       /* First the special round:
#	 *   without InvMixColumn
#	 *   with extra KeyAddition
#	 */
#	KeyAddition(a,rk[ROUNDS],BC);
#	Substitution(a,Si,BC);
#	ShiftRow(a,1,BC);              

	KeyAddition(@a,$rk->[$ROUNDS],$BC);
	Substitution(@a,@Si,$BC);
	ShiftRow(@a,1,$BC);


#	
#	/* ROUNDS-1 ordinary rounds
#	 */
#	for(r = ROUNDS-1; r > rounds; r--) {
#		KeyAddition(a,rk[r],BC);
#		InvMixColumn(a,BC);      
#		Substitution(a,Si,BC);
#		ShiftRow(a,1,BC);                
#	}

	for ($r = $ROUNDS-1; $r > $rounds; $r--) {
		KeyAddition(@a,$rk->[$r],$BC);
		InvMixColumn(@a,$BC);
		Substitution(@a,@Si,$BC);
		ShiftRow(@a,1,$BC);
	}


#	
#	if (rounds == 0) {
#		/* End with the extra key addition
#		 */	
#		KeyAddition(a,rk[0],BC);
#	}    

	if ($rounds == 0) {
		KeyAddition(@a,$rk->[0],$BC);
	}

#
#	return 0;
#}

	@_[0..3] = @a;

	return 0
}





##################################
# api-ref.c

# define     DIR_ENCRYPT     0    /*  Are we encrpyting?  */
sub DIR_ENCRYPT() { 0 }
# define     DIR_DECRYPT     1    /*  Are we decrpyting?  */
sub DIR_DECRYPT() { 1 }
# define     MODE_ECB        1    /*  Are we ciphering in ECB mode?   */
sub MODE_ECB() { 1 }
# define     MODE_CBC        2    /*  Are we ciphering in CBC mode?   */
sub MODE_CBC() { 2 }
# define     MODE_CFB1       3    /*  Are we ciphering in 1-bit CFB mode? */
sub MODE_CFB1() { 3 }
# define     TRUE            1
sub TRUE() { 1 }
# define     FALSE           0
sub FALSE() { 0 }
# define	BITSPERBLOCK		128		/* Default number of bits in a cipher block */
sub BITSPERBLOCK() { 128 }

# /*  Error Codes - CHANGE POSSIBLE: inclusion of additional error codes  */
#define     BAD_KEY_DIR        -1  /*  Key direction is invalid, e.g., unknown value */
#define     BAD_KEY_MAT        -2  /*  Key material not of correct length */
#define     BAD_KEY_INSTANCE   -3  /*  Key passed is not valid  */
#define     BAD_CIPHER_MODE    -4  /*  Params struct passed to cipherInit invalid */
#define     BAD_CIPHER_STATE   -5  /*  Cipher in wrong state (e.g., not initialized) */
#define     BAD_CIPHER_INSTANCE   -7 

# /*  CHANGE POSSIBLE:  inclusion of algorithm specific defines  */
#define     MAX_KEY_SIZE	64  /* # of ASCII char's needed to represent a key */
sub MAX_KEY_SIZE() { 64 }
#define     MAX_IV_SIZE		BITSPERBLOCK/8  /* # bytes needed to represent an IV  */
sub MAX_IV_SIZE() { BITSPERBLOCK/8 }



#int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial)
#{
#	word8 k[4][MAXKC];
#	int i, j, t;

sub makeKey($$$$) {

	my ($key, $direction, $keyLen, $keyMaterial) = @_;
	
	#$keyLen = length $keyMaterial; # hey, it's perl :-)
	
	my @k;
	
#	
#	if (key == NULL) {
#		return BAD_KEY_INSTANCE;
#	}

	unless ( defined $key and ref $key eq 'HASH') {
		die "BAD_KEY_INSTANCE";
	}

#
#	if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
#		key->direction = direction;
#	} else {
#		return BAD_KEY_DIR;
#	}

	if ($direction == DIR_ENCRYPT or $direction == DIR_DECRYPT) {
		$key->{direction} = $direction
	} else {
		die "BAD_KEY_DIR";
	}

#
#	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 
#		key->keyLen = keyLen;
#	} else {
#		return BAD_KEY_MAT;
#	}

	if ($keyLen == 128 or $keyLen == 192 or $keyLen == 256) {
		$key->{keyLen} = $keyLen
	} else {
		die "BAD_KEY_MAT";
	}

#
#	if ( keyMaterial ) {
#		strncpy(key->keyMaterial, keyMaterial, keyLen/4);
#	}

	if (defined $keyMaterial) {
		$key->{keyMaterial} = substr ($keyMaterial,0,$keyLen/4)
	}

#
#	/* initialize key schedule: */ 
#	for(i = 0; i < key->keyLen/8; i++) {
#		t = key->keyMaterial[2*i];
#		if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
#		else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; 
#		else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; 
#		else return BAD_KEY_MAT;
#		
#		t = key->keyMaterial[2*i+1];
#		if ((t >= '0') && (t <= '9')) j ^= (t - '0');
#		else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); 
#		else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); 
#		else return BAD_KEY_MAT;
#		
#		k[i % 4][i / 4] = (word8) j; 
#	}	

	my $i;
	my @keyMaterial = unpack 'A2'x(length($key->{keyMaterial})/2), $key->{keyMaterial};
	for $i (0..$keyLen/8-1) {
		$k[$i % 4][$i / 4] = hex $keyMaterial[$i];
	}
#	
#	rijndaelKeySched (k, key->keyLen, key->blockLen, key->keySched);

	#my @W;
	#rijndaelKeySched(@k, $key->{keyLen}, $key->{blockLen}, @W);
	
	rijndaelKeySched(@k, $key->{keyLen}, $key->{blockLen}, $key->{keySched});
	

#	$key->{keySched} = \@W;
	
#	
#	return TRUE;
#}
	$_[0] = $key;
	
	return TRUE;
}



#int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
#{
#	int i, j, t;

sub cipherInit($$;$) {
	
	my ($cipher, $mode, $IV) = @_;
	
	my $i;

#	
#	if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
#		cipher->mode = mode;
#	} else {
#		return BAD_CIPHER_MODE;
#	}

	if ($mode == MODE_ECB or $mode == MODE_CBC or $mode == MODE_CFB1) {
		$cipher->{mode} = $mode
	} else {
		die "BAD_CIPHER_MODE";
	}

#	
#	if (IV != NULL) {
#		for(i = 0; i < cipher->blockLen/8; i++) {		
#			t = IV[2*i];
#			if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
#			else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; 
#			else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; 
#			else return BAD_CIPHER_INSTANCE;
#		
#			t = IV[2*i+1];
#			if ((t >= '0') && (t <= '9')) j ^= (t - '0');
#			else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); 
#			else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); 
#			else return BAD_CIPHER_INSTANCE;
#			
#			cipher->IV[i] = (BYTE) j;
#		} 
#	}

	if (defined $IV) {
		# my @block = unpack 'C'x(length $IV), $IV;
		# for $i (0..$cipher->{blockLen}/8-1) {
		#	$cipher->{IV}[$i] = $block[$i];
		# }
		$cipher->{IV} = [ unpack 'C'x(length $IV), $IV ]
	}

#
#	return TRUE;
#}

	$_[0] = $cipher;
	return TRUE;
}




#int blockEncrypt(cipherInstance *cipher,
#	keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
#{
#	int i, j, t, numBlocks;
#	word8 block[4][MAXBC];

sub blockEncrypt($$$$$) {

	my ($cipher, $key, $input, $inputLen, $outBuffer) = @_;
	
	my ($i,$j,$t,$numBlocks,@block);

#
#	
#        /* check parameter consistency: */
#       if (key == NULL ||
#                key->direction != DIR_ENCRYPT ||
#                (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)) {
#                return BAD_KEY_MAT;
#        }

	if (not defined $key or $key->{direction} != DIR_ENCRYPT or
	    ($key->{keyLen} != 128 and $key->{keyLen} != 192 and $key->{keyLen} != 256)) {
		die "BAD_KEY_MAT"
	}

#        if (cipher == NULL ||
#                (cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||
#                (cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) {
#                return BAD_CIPHER_STATE;
#        }
	
	if (not defined $cipher or ($cipher->{mode} != MODE_ECB and $cipher->{mode} != MODE_CBC and $cipher->{mode} != MODE_CFB1) or
	    ($cipher->{blockLen} != 128 and $cipher->{blockLen} != 192 and $cipher->{blockLen} != 256)) {
		die "BAD_CIPHER_STATE";
	}
	
#
#
#	numBlocks = inputLen/cipher->blockLen;

	$numBlocks = $inputLen/$cipher->{blockLen};

#	
#	switch (cipher->mode) {
#	case MODE_ECB: 
#		for (i = 0; i < numBlocks; i++) {
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				for(t = 0; t < 4; t++)
#				/* parse input stream into rectangular array */
#					block[t][j] = input[4*j+t] & 0xFF;
#			}
#			rijndaelEncrypt (block, key->keyLen, cipher->blockLen, key->keySched);
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				/* parse rectangular array into output ciphertext bytes */
#				for(t = 0; t < 4; t++)
#					outBuffer[4*j+t] = (BYTE) block[t][j];
#			}
#		}
#		break;

	if ($cipher->{mode} == MODE_ECB) {
		for $i (0..$numBlocks-1) {
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$block[$t][$j] = $input->[4*$j+$t] & 0xFF;
				}
			}
			rijndaelEncrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$outBuffer->[4*$j+$t] = $block[$t][$j];
				}
			}
		}
	}

#		
#	case MODE_CBC:
#		for (j = 0; j < cipher->blockLen/32; j++) {
#			for(t = 0; t < 4; t++)
#			/* parse initial value into rectangular array */
#					block[t][j] = cipher->IV[t+4*j] & 0xFF;
#			}
#		for (i = 0; i < numBlocks; i++) {
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				for(t = 0; t < 4; t++)
#				/* parse input stream into rectangular array and exor with 
#				   IV or the previous ciphertext */
#					block[t][j] ^= input[4*j+t] & 0xFF;
#			}
#			rijndaelEncrypt (block, key->keyLen, cipher->blockLen, key->keySched);
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				/* parse rectangular array into output ciphertext bytes */
#				for(t = 0; t < 4; t++)
#					outBuffer[4*j+t] = (BYTE) block[t][j];
#			}
#		}
#		break;

	elsif ($cipher->{mode} == MODE_CBC) {
		for $j (0..$cipher->{blockLen}/32-1) {
			for $t (0..3) {
				$block[$t][$j] = $cipher->{IV}[$t+4*$j] & 0xFF
			}
		}
		for $i (0..$numBlocks-1) {
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$block[$t][$j] ^= $input->[4*$j+$t] & 0xFF;
				}
			}
			rijndaelEncrypt(@block,$key->{keyLen},$cipher->{blockLen}, $key->{keySched});
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$outBuffer->[4*$j+$t] = $block[$t][$j];
				}
			}
		}
	}

#	
#	default: return BAD_CIPHER_STATE;
#	}

	else { die "BAD_CIPHER_STATE" }

#	
#	return numBlocks*cipher->blockLen;
#}
	# @_ = ($cipher, $key, $input, $inputLen, $outBuffer);
	$_[4] = $outBuffer;
	
	return $numBlocks * $cipher->{blockLen};
}




#int blockDecrypt(cipherInstance *cipher,
#	keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
#{
#	int i, j, t, numBlocks;
#	word8 block[4][MAXBC];

sub blockDecrypt($$$$$) {
	
	my ($cipher, $key, $input, $inputLen, $outBuffer) = @_;
	
	my ($i,$j,$t,$numBlocks,@block);

#
#	if (cipher == NULL ||
#		key == NULL ||
#		key->direction == DIR_ENCRYPT ||
#		cipher->blockLen != key->blockLen) {
#		return BAD_CIPHER_STATE;
#	}

	if (not defined $cipher or not defined $key or $key->{direction} == DIR_ENCRYPT or $cipher->{blockLen} != $key->{blockLen}) {
		die "BAD_CIPHER_STATE";
	}


#
#       /* check parameter consistency: */
#        if (key == NULL ||
#                key->direction != DIR_DECRYPT ||
#                (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)) {
#                return BAD_KEY_MAT;
#        }

	if (not defined $key or $key->{direction} != DIR_DECRYPT or
		($key->{keyLen} != 128 and $key->{keyLen} != 192 and $key->{keyLen} != 256)) {
			die "BAD_KEY_MAT";
	}

#        if (cipher == NULL ||
#                (cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||
#                (cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) {
#                return BAD_CIPHER_STATE;
#        }

	if (not defined $cipher or ($cipher->{mode} != MODE_ECB and $cipher->{mode} != MODE_CBC and $cipher->{mode} != MODE_CFB1) or
	    ($cipher->{blockLen} != 128 and $cipher->{blockLen} != 192 and $cipher->{blockLen} != 256)) {
		die "BAD_CIPHER_STATE";
	}

#	
#
#	numBlocks = inputLen/cipher->blockLen;

	$numBlocks = $inputLen / $cipher->{blockLen};

#	
#	switch (cipher->mode) {
#	case MODE_ECB: 
#		for (i = 0; i < numBlocks; i++) {
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				for(t = 0; t < 4; t++)
#				/* parse input stream into rectangular array */
#					block[t][j] = input[4*j+t] & 0xFF;
#			}
#			rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched);
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				/* parse rectangular array into output ciphertext bytes */
#				for(t = 0; t < 4; t++)
#					outBuffer[4*j+t] = (BYTE) block[t][j];
#			}
#		}
#		break;

	if ($cipher->{mode} == MODE_ECB) {
		for $i (0..$numBlocks-1) {
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$block[$t][$j] = $input->[4*$j+$t] & 0xFF;
				}
			}
			rijndaelDecrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$outBuffer->[4*$j+$t] = $block[$t][$j];
				}
			}
		}
	}


#		
#	case MODE_CBC:
#		/* first block */
#		for (j = 0; j < cipher->blockLen/32; j++) {
#			for(t = 0; t < 4; t++)
#			/* parse input stream into rectangular array */
#				block[t][j] = input[4*j+t] & 0xFF;
#		}

	elsif ($cipher->{mode} == MODE_CBC) {
		for $j (0..$cipher->{blockLen}/32-1) {
			for $t (0..3) {
				$block[$t][$j] = $input->[$t+4*$j] & 0xFF
			}
		}


#		rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched);

		rijndaelDecrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});

#		
#		for (j = 0; j < cipher->blockLen/32; j++) {
#			/* exor the IV and parse rectangular array into output ciphertext bytes */
#			for(t = 0; t < 4; t++)
#				outBuffer[4*j+t] = (BYTE) (block[t][j] ^ cipher->IV[t+4*j]);
#		}

		for $j (0.. $cipher->{blockLen}/32-1) {
			for $t (0..3) {
				$outBuffer->[4*$j+$t] = $block[$t][$j] ^ $cipher->{IV}[$t+4*$j]
			}
		}

#		
#		/* next blocks */
#		for (i = 1; i < numBlocks; i++) {
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				for(t = 0; t < 4; t++)
#				/* parse input stream into rectangular array */
#					block[t][j] = input[cipher->blockLen/8+4*j+t] & 0xFF;
#			}
#			rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched);
#			
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				/* exor previous ciphertext block and parse rectangular array 
#				       into output ciphertext bytes */
#				for(t = 0; t < 4; t++)
#					outBuffer[cipher->blockLen/8+4*j+t] = (BYTE) (block[t][j] ^ 
#						input[4*j+t-4*cipher->blockLen/32]);
#			}
#		}
#		break;

		for $i (1..$numBlocks-1) {
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$block[$t][$j] ^= $input->[$cipher->{blockLen}/8+4*$j+$t] & 0xFF;
				}
			}
			rijndaelDecrypt(@block,$key->{keyLen},$cipher->{blockLen}, $key->{keySched});
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$outBuffer->[$cipher->{blockLen}/8+4*$j+$t] =
						$block[$t][$j] ^ $input->[4*$j+$t-4*$cipher->{blockLen}/32];
				}
			}
		}
	}




#	
#	default: return BAD_CIPHER_STATE;

	else { die "BAD_CIPHER_STATE" }

#	}
#	
#	return numBlocks*cipher->blockLen;
#}

	$_[4] = $outBuffer;
	
	return $numBlocks * $cipher->{blockLen};
}


#/**
# *	cipherUpdateRounds:
# *
# *	Encrypts/Decrypts exactly one full block a specified number of rounds.
# *	Only used in the Intermediate Value Known Answer Test.	
# *
# *	Returns:
# *		TRUE - on success
# *		BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)
# */
#int cipherUpdateRounds(cipherInstance *cipher,
#	keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds)
#{
	
sub cipherUpdateRounds($$$$$$) {
	
	my ($cipher, $key, $input, $inputLen, $outBuffer, $rounds) = @_;
		
#	int j, t;
#	word8 block[4][MAXBC];

	my ($j,$t,@block);

#
#	if (cipher == NULL ||
#		key == NULL ||
#		cipher->blockLen != key->blockLen) {
#		return BAD_CIPHER_STATE;
#	}

	if (not defined $cipher or not defined $key or $key->{direction} == DIR_ENCRYPT or $cipher->{blockLen} != $key->{blockLen}) {
		die "BAD_CIPHER_STATE";
	}


#
#	for (j = 0; j < cipher->blockLen/32; j++) {
#		for(t = 0; t < 4; t++)
#			/* parse input stream into rectangular array */
#			block[t][j] = input[4*j+t] & 0xFF;
#	}

	for $j (0..$cipher->{blockLen}/32-1) {
		for $t (0..3) {
			$block[$t][$j] = $input->[4*$j+$t] & 0xFF
		}
	}

#	switch (key->direction) {
#	case DIR_ENCRYPT:
#		rijndaelEncryptRound (block, key->keyLen, cipher->blockLen, 
#				key->keySched, rounds);
#	break;

	if ($key->{direction} == DIR_ENCRYPT) {
		rijndaelEncryptRound(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched}, $rounds);
	}

#		
#	case DIR_DECRYPT:
#		rijndaelDecryptRound (block, key->keyLen, cipher->blockLen, 
#				key->keySched, rounds);
#	break;

	elsif ($key->{direction} == DIR_DECRYPT) {
		rijndaelDecryptRound(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched}, $rounds);
	}

#		
#	default: return BAD_KEY_DIR;
#	} 

	else {
		die "BAD_KEY_DIR"
	}

#	for (j = 0; j < cipher->blockLen/32; j++) {
#		/* parse rectangular array into output ciphertext bytes */
#		for(t = 0; t < 4; t++)
#			outBuffer[4*j+t] = (BYTE) block[t][j];
#	}

	for $j (0..$cipher->{blockLen}/32-1) {
		for $t (0..3) {
			$outBuffer->[4*$j+$t] = $block[$t][$j];
		}
	}

#	
#	return TRUE;

	return TRUE;

#}
#

}

#####################################################################################
# my code
#####################################################################################
#
#
#
#
#
#
#
#
#
#
#
#
#
#

#
# objektinterface
#

sub DEFAULT_BLOCKSIZE() { 128 }
sub DEFAULT_KEYSIZE() { 256 }

sub new {
	my ($class,$key,$mode) = @_;

 	my $blocksize = DEFAULT_BLOCKSIZE; # FIXME konfigurierbar
	my $keysize = DEFAULT_KEYSIZE;
	my $ENkeyInst = { blockLen => $blocksize };
	my $DEkeyInst = { blockLen => $blocksize };
	$mode = MODE_ECB unless defined $mode;
	
	# FIXME check keylength

	# FIXME, compatibility mode for Crypt::Rijndael
	$key = join '', unpack 'H*', $key;

	eval { makeKey($ENkeyInst, DIR_ENCRYPT, $keysize, $key) };
	die $@ if $@;

	eval { makeKey($DEkeyInst, DIR_DECRYPT, $keysize, $key) };
	die $@ if $@;

	my $cipherInst = { blockLen => $blocksize };
	my $IV = "\0" x ($blocksize/8);
	eval { cipherInit($cipherInst, $mode, $IV) };
	die $@ if $@;
	
	my $self = {
		cipherInst => $cipherInst,
		ENkeyInst => $ENkeyInst,
		DEkeyInst => $DEkeyInst,
		IV => $IV,
		keysize => $keysize,
		blocksize => $blocksize
	};
	
	bless $self, ref($class) || $class;
}

sub encrypt {
	my ($self,$data) = @_;
	my $out;
	for (my $i=0; $i < length($data) / ($self->{blocksize}/8); $i++) {
		my $tmp = [];
		my @block = unpack 'C'x($self->{blocksize}/8),
			substr($data,$i*$self->{blocksize}/8,$self->{blocksize}/8);
		eval { 
			my $res = blockEncrypt($self->{cipherInst}, $self->{ENkeyInst}, \@block, $self->{blocksize}, $tmp);
		};
		die $@ if $@;
		$out .= pack 'C'x($self->{blocksize}/8), @$tmp;
	}
	return unless defined $out;
	$out;
}

sub decrypt {
	my ($self,$data) = @_;
	my $out;
	for (my $i=0; $i < length($data) / ($self->{blocksize}/8); $i++) {
		my $tmp = [];
		my @block = unpack 'C'x($self->{blocksize}/8),
			substr($data,$i*$self->{blocksize}/8,$self->{blocksize}/8);
		eval { 
			my $res = blockDecrypt($self->{cipherInst}, $self->{DEkeyInst}, \@block, $self->{blocksize}, $tmp);
		};
		die $@ if $@;
		$out .= pack 'C'x($self->{blocksize}/8), @$tmp;
	}
	return unless defined $out;
	$out;
}


sub rijndael_encrypt($$$;$$) {
	my ($key, $mode, $data, $keysize, $blocksize) = @_;

	$keysize = 128 unless defined $keysize;
	$blocksize = 128 unless defined $blocksize;
	
	my $keyInst = { blockLen => $blocksize };
	
	if (length $key < $keysize/4) {
		$key .= "0" x ($keysize/4 - length $key);
		warn "rijndael_encrypt: padded key to keysize ($keysize)\n";
	} elsif (length $key > $keysize/4) {
		$key = substr $key, 0, $keysize/4;
		warn "rijndael_encrypt: truncated key to keysize ($keysize)\n";
	}
	
	if (length($data) % ($blocksize/8)) {
		$data .= "0" x ($blocksize/8 - (length($data) % ($blocksize/8)));
		warn "rijndael_encrypt: padded data to multiple of blocksize ($blocksize)\n";
	}
	
	my $res;

	eval { makeKey($keyInst, DIR_ENCRYPT, $keysize, $key) };
	die $@ if $@;
		
	my $cipherInst = { blockLen => $blocksize };

	my $IV = "\0" x ($blocksize/8);

	eval { cipherInit($cipherInst, $mode, $IV) };
	die $@ if $@;
	
	my $out;
	
	my $i;
	for ($i=0; $i < length($data) / ($blocksize/8); $i++) {
		my $tmp = [];
		my @block = unpack 'C'x($blocksize/8), substr($data,$i*$blocksize/8,$blocksize/8);
		eval { 
			my $res = blockEncrypt($cipherInst, $keyInst, \@block, $blocksize, $tmp);
		};
		die $@ if $@;
		$out .= pack 'C'x($blocksize/8), @$tmp;
	}
	
	return unless defined $out;
	$out;
}



sub rijndael_decrypt($$$;$$) {
	my ($key, $mode, $data, $keysize, $blocksize) = @_;
	
	$keysize = 128 unless defined $keysize;
	$blocksize = 128 unless defined $blocksize;
	
	my $keyInst = { blockLen => $blocksize };

	if (length $key < ($keysize/4)) {
		$key .= "0" x ($keysize/4 - length $key);
		warn "rijndael_decrypt: padded key to keysize ($keysize)\n";
	} elsif (length $key > $keysize/4) {
		$key = substr $key, 0, $keysize/4;
		warn "rijndael_decrypt: truncate key to keysize ($keysize)\n";
	}
	
	my $res;

	eval { makeKey($keyInst, DIR_DECRYPT, $keysize, $key) };
	die $@ if $@;
		
	my $cipherInst = { blockLen => $blocksize };

	my $IV = "\0" x ($blocksize/8);

	eval { cipherInit($cipherInst, $mode, $IV) };
	die $@ if $@;
	
	my $out;
	my $i;
		
	for ($i=0; $i < length($data) / ($blocksize/8); $i++) {
		my $tmp = [];
		my @block = unpack 'C'x($blocksize/8), substr($data,$i*$blocksize/8,$blocksize/8);
		eval { 
			blockDecrypt($cipherInst, $keyInst, \@block, $blocksize, $tmp) 
		};
		die $@ if $@;
		$out .= pack 'C'x($blocksize/8), @$tmp;
	}
	
	return unless defined $out;
	$out;
}

####################################################
# 
# Interface for Crypt::CBC
#
####################################################

# return keysize in bytes
sub keysize { 
	my $self = shift;
	if (defined $self and ref $self and defined $self->{keysize}) {
		return $self->{keysize}/8
	}
	return DEFAULT_KEYSIZE/8
}

# return blocksize in bytes
sub blocksize {
	my $self = shift;
	if (defined $self and ref $self and defined $self->{blocksize}) {
		return $self->{blocksize}/8
	}
	return DEFAULT_BLOCKSIZE/8
}

1; # make require happy :-)

__END__

=head1 NAME

Crypt::Rijndael_PP - Perl implementation of Rijndael

=head1 DISCLAIMER

This is a pure perl implementation of the new AES Rijndael.
You want to use C<Crypt::Rijndael> where available. This implementation
is really slow, but I am working on it.

=head1 SYNOPSIS

 # Functional style
 use Crypt::Rijndael_PP ':all';

 $key = '1234567890ABCDEF' x 4; # 256bit hex number

 # keysize = 256bit, blocksize = 128bit
 $c_txt = rijndael_encrypt($key, MODE_CBC, $data,  256, 128);
 $p_txt = rijndael_decrypt($key, MODE_CBC, $c_txt, 256, 128);


 # OO style
 # same interface as Crypt::Rijndael
 use Crypt::Rijndael_PP;

 $cipher = Crypt::Rijndael_PP->new( pack('H*', $key), MODE_CBC );

 $c_txt = $cipher->encrypt($data);
 $p_txt = $cipher->decrypt($c_txt);

=head1 DESCRIPTION

This modules shares the OO style interface with C<Crypt::Rijndael>
from Rafael R. Sevilla.

=over 4

=item

Supported modes: Electronic CodeBook (MODE_ECB) and Cipher Block Chaining
(MODE_CBC). Please use C<Crypt::CBC> for CBC-Mode, as my CBC is not compatible
with neither C<Crypt::CBC> nor C<Crypt::Rijndael> and it is subject to change
in the near future. When using C<Crypt::CBC> this module is 100% compatible to
C<Crypt::Rijndael> and you can decrypt and encrypt your data with both modules!

=item

Supported keysizes: 128, 192 and 256 (default)

=item

Supported blocksizes: 128 (default), 192 and 256

=back

If the size of the key does not match the given
keysize then the key is padded with "0" (hex) or
truncated to the right size.

The last data block is padded with "\0" if it does not match
a multiple of the blocksize.

Warnings a raised in both cases.

=head1 EXAMPLES

Using C<Crypt::CBC>

 use Crypt::CBC;

 my $key = 'my secret key';
 my $input = 'The answer is 42.';
 my $cipher = new Crypt::CBC($key,'Rijndael_PP');

 my $ciphertext = $cipher->encrypt($input);
 my $plaintext  = $cipher->decrypt($ciphertext);


 # - or -

 #!/usr/local/bin/perl -w
 #
 # Usage: r.pl e "my secret key" < in > out
 #
 use strict;
 use Crypt::CBC;
 die "Usage: $0 mode([ed]) key\n" unless @ARGV == 2;
 my $cipher = new Crypt::CBC($ARGV[1],'Rijndael_PP');
 $cipher->start($ARGV[0]);
 my $buffer;
 while( read(STDIN, $buffer, 1024) ) {
	 print $cipher->crypt($buffer);
 }
 print $cipher->finish;


=head1 LIMITATIONS

This implementation is really slow. I'm trying to tweak the
performance in coming releases.

CBC-Mode is not yet compatible to C<Crypt::Rijndael>. But you are
advised to use C<Crypt::CBC> for this mode anyway.

=head1 SEE ALSO

L<Crypt::Rijndael>

L<Crypt::CBC>

L<http://csrc.nist.gov/encryption/aes/>

=head1 COPYRIGHT

This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

 Copyright 2001 Christian Lackas
 Copyright 2000 Vincent Rijmen and Joan Daemen

=head1 AUTHORS

The original algorithm was developed by Vincent Rijmen and Joan Daemen.

This release was made by Christian Lackas <delta@lackas.net>.
http://www.lackas.net/. It is based on the reference implementation
for the AES contest. At present I am working on a faster version.

=cut
